Skip to main content
The v2 Auth Component is in preview. APIs and component props may change before release.
The Auth Component is a pre-built React component that collects end-user credentials, stores them in the Credential Vault, and creates a Credential. Credentials never touch your systems. It handles source selection, username/password capture, interactions (MFA, security questions), and error states out of the box.
Want full customization and control over the UX? See Building your auth flow to build your own using the API directly.

How it works

  1. Your server creates a session token via POST /v2/token
  2. Your frontend mounts <DeckAuthComponent /> with the token and all configuration
  3. The component renders a secure UI where the user selects a source and enters credentials
  4. Credentials go from the component directly to the Deck API and into the Credential Vault. They never touch your page
  5. On success, the component returns the new Credential ID via onSuccess

Restrictions

  • Only supports auth_method: username_password
  • Does not support chaining to tasks with inputs
  • Does not support source_fields on the credential

Installation

npm install @deck/auth
import { DeckAuthComponent } from '@deck/auth';
React 18+ is a peer dependency.

Quick example

Create a session token on your server:
Server
const response = await fetch('https://api.deck.co/v2/token', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer sk_live_...',
  },
});

const { token } = await response.json();
Mount the component in your React app:
Client
<DeckAuthComponent
  token={token}
  sourceId="src_abc123"
  externalId="user_12345"
  taskId="task_x9y8z7..."
  onSuccess={({ credentialId, externalId, taskRunId, verified }) => {
    console.log('Credential created:', credentialId);
  }}
  onError={({ type, code, message }) => {
    console.error('Auth failed:', code, message);
  }}
  onClose={() => {
    // User dismissed the component. Unmount, navigate, etc.
  }}
/>

Session token

Every auth component session starts with a server-side token. The token is authentication only. It proves the request came from your backend. All configuration (sourceId, appearance, etc.) is passed on the component, not the token.

POST /v2/token

Creates a session token for the Auth Component. Authentication: Authorization: Bearer sk_live_... Request body: None Response (201):
{
  "id": "tok_abc123...",
  "object": "token",
  "token": "tk_abc123...",
  "expires_at": "2026-04-10T12:30:00Z",
  "created_at": "2026-04-10T12:00:00Z",
  "request_id": "req_xyz789"
}
FieldTypeDescription
idstringToken identifier, prefixed tok_
objectstringAlways token
tokenstringThe token value to pass to the component, prefixed tk_
expires_atISO 860130 minutes from creation
created_atISO 8601Creation timestamp
request_idstringRequest ID for support

Token lifecycle

  • Tokens expire 30 minutes after creation
  • Expired tokens return a clear error to onError

Component props

PropTypeDescription
tokenstringRequired. Session token from POST /v2/token.
sourceIdstring | string[]Pre-select a single source (skips picker) or filter to multiple.
credentialIdstringIf provided, enters Update Mode. Re-collects credentials for an existing credential.
externalIdstringYour user ID. Passed back in onSuccess and persisted on the credential.
taskIdstringIf provided, fires a verification task run after credential creation/update.
appearanceAppearanceConfigFull theming control. See Appearance.
taskRunView"status" | "live"How the task run is displayed while executing. Defaults to "status".
onSuccess(data) => voidRequired. Called when credential creation/update succeeds.
onError(data) => voidCalled on failure. See Error handling.
onClose() => voidIf provided, shows a close button. Called when user clicks it. If omitted, no close button is rendered.
The component does not own its lifecycle. Your app does. When onClose fires, you decide what happens (unmount, navigate, show a confirmation, etc.).

Callbacks

onSuccess

onSuccess: (data: {
  credentialId: string;
  externalId: string | null;
  taskRunId: string | null;
  verified: boolean | null;
}) => void;
FieldTypeDescription
credentialIdstringThe created or updated credential
externalIdstring | nullYour external ID, if provided
taskRunIdstring | nullVerification task run ID. null if no taskId was passed
verifiedboolean | nulltrue if run succeeded, false if run failed, null if no taskId was passed

onError

onError: (data: {
  type: string;
  code: string;
  message: string;
}) => void;
type is the error category. code is the machine-readable identifier. message is human-readable and may change. Switch on type and code, not message. See Error handling for all error codes.

onClose

onClose: () => void;
If onClose is provided, the component renders a close button. When clicked, onClose fires and you handle the teardown. If onClose is omitted, no close button is rendered. Pressing Escape also fires onClose if provided. If a task run is in progress when the user closes the component, the task run continues running in the background. To cancel it, use the cancel endpoint from your onClose handler.

Source selection

The sourceId prop controls what the user sees before credential capture.
sourceIdBehavior
Not providedFull source search. User searches across all sources in your organization.
Single ID ("src_abc123")Skips source selection. Goes straight to credential capture.
Array (["src_abc", "src_def"])Filtered selection. User picks from the provided sources in your organization.

Update mode

Pass a credentialId to re-collect credentials for an existing credential instead of creating a new one.
credentialIdsourceIdBehavior
absentabsentCreate mode. Full source search.
absentpresentCreate mode. Skip/filter source selection.
presentignoredUpdate mode. Skip source selection, patch existing credential.
<DeckAuthComponent
  token={token}
  credentialId="cred_existing_456"
  externalId="user_12345"
  onSuccess={({ credentialId, externalId }) => {
    console.log('Credentials updated for:', credentialId);
  }}
/>

Task linking

Pass a taskId to verify credentials immediately after creation. The component fires a task run using the new credential, and the task run view stays visible while it executes.
taskIdRun outcomeCredential statusonSuccess payload
absentn/aunverified{ credentialId, externalId, taskRunId: null, verified: null }
presentrun succeedsverified{ credentialId, externalId, taskRunId, verified: true }
presentrun failsverified{ credentialId, externalId, taskRunId, verified: false }
The credential becomes verified as long as the agent authenticates successfully, even if the task run itself fails. A failed run does not delete or invalidate the credential.

taskRunView

With taskId present, the task run view is shown while the run executes:
  • "status": spinner with status text (e.g., “Connecting…”, “Verifying credentials…”)
  • "live": live view of the task run
Without taskId, no task run view is shown.

Appearance

Customize the component’s look via the appearance prop.
<DeckAuthComponent
  token={token}
  appearance={{
    theme: 'dark',
    variables: {
      colorPrimary: '#0066FF',
      borderRadius: 8,
    },
    layout: {
      logoUrl: 'https://example.com/logo.svg',
    },
  }}
  onSuccess={handleSuccess}
/>

Theme

ValueDescription
"default"Light theme with neutral styling
"dark"Dark theme

Variables

VariableDescription
colorPrimaryPrimary button and accent color
colorBackgroundCard background
colorForegroundMain text color
colorPrimaryForegroundText on primary buttons
colorNeutralNeutral accent
colorDangerError states
colorSuccessSuccess states
colorMutedMuted backgrounds (hover, etc.)
colorMutedForegroundSecondary text
colorBorderBorder color
colorInputInput border color
colorRingFocus ring color
fontFamilyFont stack
borderRadiusBorder radius in pixels (e.g., 8)
shadowShadow token for card/elevated surfaces

Layout

VariableDescription
logoUrlLogo shown in the card header (your logo, not Deck’s)
logoPlacement"top" or "left"

Interactions

Sources may require additional input mid-flow: an MFA code, a security question, an account selection. The component handles these automatically as interactions: a generic pause-and-prompt primitive. When an interaction is required:
  1. The component transitions to an interaction step and renders the fields from the source’s response
  2. The user fills in the fields and submits
  3. The source validates. On accept, the flow continues
  4. Some sources require multiple sequential interactions (e.g., MFA code then a security question)
The component does not enforce its own interaction timeout. Timeout windows are set by the source and handled by the backend. The user cannot go back to credential entry from an interaction step (credentials have already been created). See Interactions for more on how Deck models interactions.

Error handling

All errors surface through onError with a uniform { type, code, message } shape.

Token errors

TypeCodeDescription
requesttoken_invalidInvalid or expired token

Credential errors

TypeCodeDescription
authauth_invalidCredentials rejected by the source
authauth_method_not_supportedSource does not support the attempted auth method
authpassword_reset_requiredSource is forcing a password reset
authaccount_lockedAccount is locked at the source
requestcredential_not_foundUpdate mode: credentialId does not exist
requestcredential_deletedUpdate mode: credential has been deleted

Source errors

TypeCodeDescription
requestsource_not_foundThe sourceId does not exist
sourcesource_not_availableSource is temporarily unreachable
sourcesource_errorSource returned an unexpected failure

Interaction errors

TypeCodeDescription
interactioninteraction_timeoutInteraction window expired (source-defined)
requestinteraction_input_invalidSubmitted input didn’t match the declared field schema

Error behavior

  • Token errors (token_invalid) terminate the session. Create a new token and remount.
  • Credential errors (auth_invalid, account_locked, etc.) terminate the session.
  • Interaction errors (interaction_timeout) terminate the session. Wrong user input is not an error, the source emits another prompt and the user retries in-place.