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

# Vault

> Manage encrypted credentials with the Python SDK

# Vault Client

The Vault client provides secure credential management with AES-256-GCM encryption. Store usernames, passwords, and other sensitive data for use in workflow executions.

<Note>
  All sensitive fields (`user_name`, `password`, and `tfa_secret`) are automatically encrypted by the SDK before being sent to CloudCruise servers. Plaintext credentials are **never** transmitted or stored.
</Note>

## Setup

```python theme={null}
from cloudcruise import CloudCruise, CloudCruiseParams

client = CloudCruise(
    CloudCruiseParams(
        api_key="your-api-key",
        encryption_key="your-encryption-key",
    )
)
```

The `encryption_key` is required for vault operations. Get it from [CloudCruise Settings](https://app.cloudcruise.com/settings/encryption-keys).

## Creating a Vault Entry

Use `client.vault.create()` to store new credentials:

```python theme={null}
from cloudcruise import VaultEntryInput

entry = client.vault.create(
    VaultEntryInput(
        domain="https://example.com",
        permissioned_user_id="unique-user-id",
        user_name="john@example.com",
        password="secret-password",
        user_alias="John's Account",
    )
)

print("Created vault entry:", entry.id)
```

### Parameters

| Parameter | Type              | Required | Description                                                            |
| --------- | ----------------- | -------- | ---------------------------------------------------------------------- |
| `entry`   | `VaultEntryInput` | Yes      | Dataclass containing the target domain, user id, and credential fields |

### VaultEntryInput Fields

| Field                      | Type   | Description                                                                                                                         |
| -------------------------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `domain`                   | `str`  | Target domain for the credentials (e.g., `https://example.com`)                                                                     |
| `permissioned_user_id`     | `str`  | Unique identifier to reference this entry in workflows                                                                              |
| `user_name`                | `str`  | Username or email for authentication                                                                                                |
| `password`                 | `str`  | Password credential                                                                                                                 |
| `secret_provider_id`       | `str`  | Bind to a [1Password](/integrations/1password) connection instead of `user_name`/`password`. Must be set together with `secret_ref` |
| `secret_ref`               | `str`  | Secret-provider item reference (e.g. `op://vaultId/itemId`) resolved live at run time                                               |
| `secret_cache_ttl_seconds` | `int`  | Override the connection's cache TTL for this credential, in seconds                                                                 |
| `user_alias`               | `str`  | Human-readable label for the entry                                                                                                  |
| `tfa_secret`               | `str`  | TOTP secret for two-factor authentication                                                                                           |
| `tfa_method`               | `str`  | TFA method: `"AUTHENTICATOR"`, `"EMAIL"`, `"MAGIC_LINK"`, or `"SMS"`                                                                |
| `persist_cookies`          | `bool` | Maintain cookies across workflow executions                                                                                         |
| `persist_local_storage`    | `bool` | Maintain local storage across executions                                                                                            |
| `persist_session_storage`  | `bool` | Maintain session storage across executions                                                                                          |
| `skip_csrf_cookies`        | `bool` | Skip injecting CSRF-related cookies (e.g. XSRF-TOKEN) during session restore                                                        |
| `allow_multiple_sessions`  | `bool` | Allow concurrent workflow sessions with these credentials                                                                           |
| `max_concurrency`          | `int`  | Maximum concurrent sessions (when `allow_multiple_sessions` is true)                                                                |
| `proxy`                    | `dict` | Proxy configuration with `enable` (bool) and `target_ip` (str)                                                                      |

## Provider-Backed Credentials (1Password)

If your workspace has a [1Password connection](/integrations/1password), you can bind a vault entry to a 1Password item instead of storing a `user_name` and `password`. CloudCruise resolves the username, password, and one-time code from 1Password at run time — **the secret values are never stored in CloudCruise**.

Use `client.secret_providers` to discover the connection and item reference, then pass `secret_provider_id` and `secret_ref` to `create()` (or `update()`):

```python theme={null}
from cloudcruise import VaultEntryInput

# 1. List the workspace's secret-provider connections
providers = client.secret_providers.list()
provider = providers[0]

# 2. List items the connection can see, and pick one
items = client.secret_providers.list_items(provider.id)
item = items[0]

# 3. Bind a vault entry to the item — no user_name/password
entry = client.vault.create(
    VaultEntryInput(
        domain="https://example.com",
        permissioned_user_id="acme-prod",
        secret_provider_id=provider.id,
        secret_ref=item.ref,
        secret_cache_ttl_seconds=300,  # optional; omit to use the connection default
    )
)
```

### SecretProvider Fields

| Field               | Type          | Description                                  |
| ------------------- | ------------- | -------------------------------------------- |
| `id`                | `str`         | Connection ID — pass as `secret_provider_id` |
| `provider_type`     | `str`         | Provider type (currently `"1password"`)      |
| `name`              | `str`         | Connection label set in the dashboard        |
| `cache_ttl_seconds` | `int \| None` | The connection's default cache TTL           |

### SecretProviderItem Fields

| Field       | Type          | Description                                                   |
| ----------- | ------------- | ------------------------------------------------------------- |
| `id`        | `str`         | Provider-side item ID                                         |
| `title`     | `str`         | Item title in 1Password                                       |
| `ref`       | `str`         | Item reference (`op://vaultId/itemId`) — pass as `secret_ref` |
| `vaultName` | `str \| None` | Name of the 1Password vault the item lives in                 |

<Note>
  Validation enforced by the SDK before the request is sent:

  * `secret_provider_id` and `secret_ref` must be provided together.
  * A provider-backed entry **cannot** also include `user_name`, `password`, or `tfa_secret` — those are resolved from the provider.
  * `secret_cache_ttl_seconds` requires `secret_provider_id`/`secret_ref` and must be a non-negative integer.
</Note>

## Getting Vault Entries

Retrieve vault entries with optional filtering:

```python theme={null}
from cloudcruise.vault import GetVaultEntriesFilters

# Get all entries
all_entries = client.vault.get()

# Get specific entry by domain and user ID
entries = client.vault.get(
    GetVaultEntriesFilters(
        domain="https://example.com",
        permissioned_user_id="unique-user-id",
    )
)

# Get entries without decrypting credentials
entries = client.vault.get(
    GetVaultEntriesFilters(
        domain="https://example.com",
        permissioned_user_id="unique-user-id",
        decryptCredentials=False,
    )
)
```

### GetVaultEntriesFilters

| Field                  | Type   | Description                                      |
| ---------------------- | ------ | ------------------------------------------------ |
| `domain`               | `str`  | Filter by target domain                          |
| `permissioned_user_id` | `str`  | Filter by user ID                                |
| `decryptCredentials`   | `bool` | Whether to decrypt credentials (default: `True`) |

<Note>
  When filtering, both `domain` and `permissioned_user_id` must be provided together.
</Note>

## Updating a Vault Entry

Update an existing vault entry:

```python theme={null}
updated_entry = client.vault.update(
    VaultEntryInput(
        domain="https://example.com",
        permissioned_user_id="unique-user-id",
        user_name="new-username@example.com",
        password="new-password",
        user_alias="Updated Account Name",
    )
)
```

### Required Fields for Update

| Field                  | Required |
| ---------------------- | -------- |
| `domain`               | Yes      |
| `permissioned_user_id` | Yes      |

All other `VaultEntryInput` fields are optional. Include only the fields you want to change.

## Deleting a Vault Entry

Delete a vault entry by domain and user ID:

```python theme={null}
client.vault.delete({
    "domain": "https://example.com",
    "permissioned_user_id": "unique-user-id",
})
```

## Using Vault Entries in Workflows

Reference vault credentials in workflow runs by passing the `permissioned_user_id` as an input variable:

```python theme={null}
from cloudcruise import GetVaultEntriesFilters, StartRunRequest, VaultEntryInput

# First, ensure the vault entry exists
entries = client.vault.get(
    GetVaultEntriesFilters(
        domain="https://login.example.com",
        permissioned_user_id="user-123",
    )
)

if not entries:
    client.vault.create(
        VaultEntryInput(
            domain="https://login.example.com",
            permissioned_user_id="user-123",
            user_name="john@example.com",
            password="secret-password",
        )
    )

# Start the workflow with the vault entry reference
run = client.runs.start(
    StartRunRequest(
        workflow_id="your-workflow-id",
        run_input_variables={
            "USER": "user-123",  # References the permissioned_user_id
        },
    )
)

result = run.wait()
print("Run completed:", result.status)
```

<Tip>
  The input variable name (e.g., `USER`) depends on how your workflow is configured. Check your workflow's input schema in the CloudCruise dashboard.
</Tip>
