> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deck.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Credentials

> A credential stores authentication details for a user on a source.

A credential represents one set of authentication details for one user on one [source](https://docs.deck.co/concepts/sources.md). If a user needs access to Hilton and Marriott, that's two credentials. Use `external_id` when creating credentials to tie them back to users in your system.

## How credentials fit in

A credential stores the auth details Deck needs to log in on behalf of a user. When you [run a task](https://docs.deck.co/concepts/task-runs.md), Deck uses the credential to authenticate a [session](https://docs.deck.co/concepts/sessions.md) against the source. You don't need to manage sessions or track login state. Just store the credential and run tasks against it.

Credentials are optional on tasks. There are two cases where you would use credentials:

* **Working with sources that require authentication.** Store your own credentials or your user's credentials in the credential vault and securely pass them to run a task.
* **Linking users in your system to Deck.** You can use credentials to link users to your system with an `external_id` and pass the `auth_method` as `none`. This provides user linking without credential storage.

## Creating a credential

Pass authentication details through the API. Deck tokenizes the secret values into the [credential vault](https://docs.deck.co/platform/credential-management.md), so its database holds tokens rather than secrets. This applies on every plan.

The credential is created with `unverified` status. It becomes `verified` the first time a task run successfully authenticates with it.

## Auth methods

| Method | Description |
| - | - |
| `username_password` | Standard username and password. |
| `source_fields` | Source-specific values only, no username or password. See [source fields as the auth method](#source-fields-as-the-auth-method). |
| `google_sso` | The user's Google Account `email` and `password`, for a source they sign in to with Google. The agent signs in through the source's Google button. |
| `apple_sso` | The user's Apple Account `email` and `password`, for a source they sign in to with Apple. The agent signs in through the source's Apple button. |
| `none` | No credentials needed (public sources). Use this to link users from your system. |

## Source fields

Some sources require additional values beyond what the `auth_method` covers, such as a `company_id` or `account_number` that sits alongside a username and password at login. Pass these values through `source_fields` inside `auth_credentials`.

`source_fields` composes with any `auth_method`. The source dictates which keys it requires; you supply the values.

```json theme={null}
{
  "source_id": "src_01HXYZ...",
  "auth_method": "username_password",
  "auth_credentials": {
    "username": "user@example.com",
    "password": "...",
    "source_fields": {
      "company_id": "ACME-4412"
    }
  },
  "external_id": "cust_42"
}
```

Keys must match `^[a-z][a-z0-9_]{0,63}$`, must not collide with reserved keys on the `auth_method` (such as `username`, `email` or `password`), and are capped at 10 entries per credential.

By default, source field values are non-secret context and are readable on read. When you retrieve a credential with [`GET /credentials/{credential_id}`](https://docs.deck.co/api-reference/credentials/retrieve-a-credential), or list credentials, the response returns `source_fields` as a map of the stored key/value pairs, so you can read back any value you saved without tokenizing it. Use this for non-sensitive identifiers like `company_id`. To vault a value instead of returning it, declare it in `tokenized` (below); tokenized values are never returned this way and appear only by name in the `tokenized` array. At task run time, the agent resolves each entry by key (for example, `{{credential.company_id}}`) into the login flow.

### Source fields as the auth method

Some sources have no username or password and log in purely on source-specific values, such as a company ID and account number. For these, set `auth_method` to `source_fields` and pass the values in `source_fields`. At least one entry is required.

```json theme={null}
{
  "source_id": "src_01HXYZ...",
  "auth_method": "source_fields",
  "auth_credentials": {
    "source_fields": {
      "company_id": "ACME-4412",
      "account_number": "88213"
    }
  },
  "external_id": "cust_42"
}
```

### Tokenizing source fields

> [!NOTE]
>
> Available on Enterprise plans.

Some source fields hold sensitive values, such as a social security number, that should never sit in plaintext or appear in API responses. Declare those fields in a `tokenized` array inside `auth_credentials`. Each entry must name a key present in `source_fields`. This mirrors [tokenizing task inputs](https://docs.deck.co/concepts/tasks.md#tokenizing-sensitive-fields).

```json theme={null}
{
  "source_id": "src_01HXYZ...",
  "auth_method": "username_password",
  "auth_credentials": {
    "username": "user@example.com",
    "password": "...",
    "source_fields": {
      "company_id": "ACME-4412",
      "member_ssn": "123-45-6789"
    },
    "tokenized": ["member_ssn"]
  }
}
```

Here `member_ssn` is vaulted and `company_id` is stored in the clear. Deck tokenizes the declared values when the credential is written, placing them in [Deck Vault](https://docs.deck.co/platform/credential-management.md) alongside the credential's auth secrets; if vaulting fails, nothing is stored. The values are restored only when a task run needs them on the source, and are scrubbed from logs like any other vaulted secret.

Tokenizing a field is more secure, since the value is vaulted and never exposed through the API. The tradeoff is that you can't query it back: tokenized fields are removed from `source_fields` entirely and only their names appear in the `tokenized` array, whereas non-tokenized fields are returned in the clear and can be read back when you retrieve the credential. The full set of fields is the union of the `source_fields` keys and `tokenized`, and `tokenized` is omitted when nothing was vaulted.

```json theme={null}
{
  "credential_id": "cred_01ABC...",
  "auth_method": "username_password",
  "auth_credentials": {
    "username": "user@example.com",
    "source_fields": {
      "company_id": "ACME-4412"
    },
    "tokenized": ["member_ssn"]
  }
}
```

Auth secrets like `password` are always vaulted regardless of `tokenized`. The array governs source fields only.

When you update a credential, only the fields you include change. Within `source_fields`, a supplied value upserts that key and an explicit `null` deletes it along with its vault token. On update, `tokenized` may only name keys you supply in the same request. Because tokenized values are never readable back through the API, changing a field's tokenization status requires re-supplying its value; fields you omit keep both their value and their current tokenization status.

## Credential statuses

| Status | Meaning |
| - | - |
| `unverified` | Stored but not yet used in a successful authentication |
| `verified` | Successfully authenticated at least once |
| `invalid` | The source rejected the credentials |
| `deleted` | Permanently removed from the credential vault, still queryable |

A credential becomes `verified` when a task run using it completes successfully. This happens automatically, and not only on the first run: if a credential marked `invalid` is used in a task run that succeeds, it returns to `verified` on its own, no update required.

A credential becomes `invalid` when a task run using it fails with an `auth_invalid` error. Any other failure leaves the status unchanged. To fix it, update the credential with correct details, which resets it to `unverified` until the next successful task run.

A `deleted` credential has been permanently removed from the credential vault. The credential object and its associated task runs are still queryable, but no new tasks can use it.

## Credential persistence

By default, every task run starts from a clean browser and logs in fresh. With credential persistence enabled, Deck saves the credential's authenticated login state (cookies and device trust) after a run and restores it on the next one. When the source honors the restored state, the run skips the login flow and repeat MFA prompts.

> [!NOTE]
>
> Persistence is best effort, and behavior varies widely by source. Deck restores the saved login state, but each source decides whether to honor its cookies and device trust. Some keep logins alive for weeks, some expire them in minutes, and some re-challenge on every visit regardless. The same source can also change its behavior at any time. When a source doesn't honor the saved state, the run logs in fresh, so always be prepared to respond to an MFA prompt through an [interaction](https://docs.deck.co/guides/interactions.md), even on credentials that have skipped it for many runs.

Enable it per credential with the `persistence` field, at creation or later with an update:

**PATCH /v2/credentials/`{credential_id}`**

```json theme={null}
{
  "persistence": { "enabled": true }
}
```

Persistence is off by default. Credential responses include the current setting as `persistence.enabled`. You can also toggle it from the credential's page in the [Console](https://console.deck.co), or enable it at creation from the [Auth Component](https://docs.deck.co/components/auth.md#component-props) via its `credentialPersistence` prop.

### Saved login state lifecycle

* **Saved after login.** Deck saves the login state once a run authenticates successfully, even if the task itself fails afterward. Runs that fail to authenticate never overwrite saved state.
* **Restored on the next run.** Later runs start from the saved login state instead of logging in. If the source rejects or has expired it, the agent logs in fresh and saves new state in the same run.
* **Skipped for `invalid` credentials.** A credential marked `invalid` never restores its saved login state. Runs log in fresh until a successful login saves new state.
* **Expires after 45 days.** Saved login state that hasn't been refreshed in 45 days is deleted automatically. Persistence stays enabled, and the next run logs in fresh and saves new state.

### Disabling persistence

Setting `enabled` to `false` permanently deletes the saved login state, as does deleting the credential. Re-enabling persistence starts over from the next successful login.

Saved login state is encrypted and never returned by the API. See [how Deck stores saved login state](https://docs.deck.co/platform/credential-management.md#saved-login-state).

## Deep dives

> [card] [Credential Vault](https://docs.deck.co/platform/credential-management.md)
>
> How Deck encrypts, stores, and deletes user credentials.

> [card] [Sessions](https://docs.deck.co/concepts/sessions.md)
>
> Compute sessions created when tasks run.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.