Registers a cloud key-vault-style credential-storage backend (Azure Key Vault, AWS Secrets Manager, or GCP Secret Manager) used to persist vault entry material.
CREATE CREDENTIAL STORAGE [IF NOT EXISTS] <name>
TYPE = { OS_KEYCHAIN | AZURE | AWS | GCP }
[DESCRIPTION '<text>']
[OPTIONS (<key> = '<value>', ...)]
[ACTIVE | INACTIVE]
## Overview CREATE CREDENTIAL STORAGE registers a cloud key-vault-style backend that persists the material for vault entries (encryption keys and credentials). Each backend row lives in vault_backends and is addressable by display_name in subsequent CREATE VAULT / CREATE CREDENTIAL statements via the IN CREDENTIAL STORAGE clause. The command mirrors the 'Add Backend' form on the GUI Credential Storage page. ## Behavior - Creates a row in vault_backends with a fresh UUID, the provided name, the backend type, and the config_json map. Non-secret config values are stored verbatim; secret auth material (for example Azure service_principal client_secret or AWS access keys) is extracted from OPTIONS at execution time and written to the local OS Keychain under profile backend::<backend_id>, then removed from config_json before persistence. - The OS Keychain backend is auto-provisioned at catalog migration time with a fixed id (00000000-0000-0000-0000-000000000001) and display_name 'OS Keychain'. Attempting to create another instance with TYPE = OS_KEYCHAIN is rejected regardless of IF NOT EXISTS. This matches the GUI, which hides OS_KEYCHAIN from the Add Backend type selector. - IF NOT EXISTS makes the statement idempotent for bootstrap scripts. A second execution with the same name returns the existing row without error. Without IF NOT EXISTS, a duplicate name fails with a uniqueness violation. - ACTIVE and INACTIVE control whether the backend can be selected as the target of new CREATE VAULT statements. INACTIVE backends are still visible via SHOW CREDENTIAL STORAGES and continue to serve existing vault entries. - The command requires the admin role. The Control Plane enforces the vault:write scope on the underlying POST /vault/backends route. ## Required auth material per backend type ### AZURE auth_method = 'service_principal' requires tenant_id, client_id, client_secret (the secret is moved to OS Keychain on creation). auth_method = 'managed_identity' requires no additional secrets. auth_method = 'cli' relies on an already-authenticated Azure CLI session on the host. auth_method = 'browser' launches a device-code flow outside of SQL (GUI-only path). key_vault_name is always required. ### AWS auth_method = 'iam_role' inherits IAM credentials from the host environment (EC2 instance profile, EKS service account, or AWS_PROFILE). auth_method = 'access_key' requires access_key_id, secret_access_key, and optionally session_token (all moved to OS Keychain). region defaults to us-east-1 if omitted. secrets_manager_prefix scopes which secrets this backend can read or write; defaults to 'delta-forge'. ### GCP auth_method = 'adc' uses Application Default Credentials from the host environment. auth_method = 'service_account' requires service_account_json (a JSON blob moved to OS Keychain). project_id is always required. ## Access Control A role used to execute this command must have the following privileges at a minimum: | Privilege | Object | Notes | |-----------|--------|-------| | admin | Catalog | Configuration commands are admin-only. Non-admin callers receive InsufficientPrivilege before the HTTP round trip. | | vault:write | Control Plane scope | Enforced server-side as defence in depth. | ## Compatibility CREATE CREDENTIAL STORAGE is a DeltaForge extension for registering secret-management backends (vaults, key stores). It is distinct from CREATE STORAGE CREDENTIAL, which registers cloud-storage access credentials (S3/ADLS/GCS).
| Name | Type | Description |
|---|---|---|
name | Specifies the unique backend name. Must be unique across the catalog; enforced by a UNIQUE constraint on vault_backends.display_name. | |
type | Specifies the backend kind. Accepted values at parse time: AZURE, AWS, GCP. OS_KEYCHAIN is parsed but rejected by the executor because the OS Keychain is the auto-provisioned singleton default and already exists under the seeded backend id '00000000-0000-0000-0000-000000000001'. | |
options | Specifies the backend-specific config map serialized into vault_backends.config_json. Azure accepts auth_method (cli, browser, managed_identity, service_principal), key_vault_name, tenant_id, client_id; secrets are stored separately in the OS Keychain under profile backend::<backend_id>. AWS accepts auth_method (access_key, iam_role), region, secrets_manager_prefix. GCP accepts auth_method (adc, service_account), project_id. | |
description | Specifies an optional human-readable description surfaced in the GUI Credential Storage page and in SHOW/DESCRIBE output. | |
active | Specifies whether the backend is immediately active. ACTIVE (default) enables it; INACTIVE soft-disables it at creation time. Toggle later via ALTER CREDENTIAL STORAGE. |
-- Register an Azure Key Vault backend using service-principal auth
CREATE CREDENTIAL STORAGE prod_azure_kv
TYPE = AZURE
OPTIONS (
auth_method = 'service_principal',
key_vault_name = 'prod-kv',
tenant_id = '00000000-0000-0000-0000-000000000000',
client_id = '00000000-0000-0000-0000-000000000000'
)
DESCRIPTION 'Production Azure Key Vault';
-- AWS Secrets Manager via IAM role
CREATE CREDENTIAL STORAGE IF NOT EXISTS prod_aws_sm
TYPE = AWS
OPTIONS (auth_method = 'iam_role', region = 'us-east-1', secrets_manager_prefix = 'delta-forge');
-- GCP Secret Manager via Application Default Credentials
CREATE CREDENTIAL STORAGE IF NOT EXISTS prod_gcp_sm
TYPE = GCP
OPTIONS (auth_method = 'adc', project_id = 'my-project');
-- Register a backend in INACTIVE state (disabled until explicitly activated)
CREATE CREDENTIAL STORAGE staging_azure
TYPE = AZURE
OPTIONS (auth_method = 'managed_identity', key_vault_name = 'staging-kv')
INACTIVE;
-- Idempotent bootstrap: safe to re-run
CREATE CREDENTIAL STORAGE IF NOT EXISTS prod_azure_kv
TYPE = AZURE
OPTIONS (auth_method = 'service_principal', key_vault_name = 'prod-kv');