Secrets store sensitive values like API keys, passwords, and tokens securely.
Secrets List - Manage API keys, passwords, and tokens
Important: Inline storage and resolution are disabled by default unless
DATAHUB_MASTER_KEYcontains at least 32 characters. Keep the same key available to every API server and worker that resolves inline secrets.
| ENV secrets do not need a master key. Their stored value must be exactly one environment-variable name matching ^[A-Z][A-Z0-9_]*$; fallback expressions such as API_KEY | development-key are rejected. A valid reference does not prove that the variable exists, so configure it on every API server and worker that can execute a consuming pipeline. |
Secret Configuration - Encrypted storage with provider options
Store the value in the database encrypted with AES-256-GCM. A valid DATAHUB_MASTER_KEY is required before an inline value can be created, updated, or resolved:
Code: api-key
Provider: inline
Value: sk_live_abc123...
Best for: Values that must be managed in the dashboard and can share a securely managed master key across all application processes.
Read the value from an environment variable:
Code: api-key
Provider: env
Value: SUPPLIER_API_KEY
The Value field contains the environment variable name, not the actual secret. The value is read at runtime.
Best for: Production, CI/CD pipelines, Docker deployments.
Reference secrets by code in step configurations.
Bearer token:
.extract('api-call', {
adapterCode: 'httpApi',
connectionCode: 'supplier-api',
url: '/products',
auth: {
type: 'BEARER',
secretCode: 'api-key',
},
})
Basic auth:
.extract('api-call', {
adapterCode: 'httpApi',
connectionCode: 'supplier-api',
url: '/products',
auth: {
type: 'BASIC',
usernameSecretCode: 'api-username',
secretCode: 'api-password',
},
})
API key header:
.extract('api-call', {
adapterCode: 'httpApi',
connectionCode: 'supplier-api',
url: '/products',
auth: {
type: 'API_KEY',
secretCode: 'api-key',
headerName: 'X-API-Key',
},
})
All secret-backed HTTP authentication requires connectionCode, and the saved
connection must define a base URL. A relative url resolves against that base
URL. An absolute url must use its exact origin, and credentials are not
forwarded across cross-origin redirects.
// In connection configuration
{
code: 'erp-db',
type: 'POSTGRES',
settings: {
host: 'db.example.com',
database: 'erp',
username: 'vendure',
passwordSecretCode: 'erp-db-password',
},
}
{
code: 'aws-storage',
type: 'S3',
settings: {
region: 'us-east-1',
accessKeyIdSecretCode: 'aws-access-key',
secretAccessKeySecretCode: 'aws-secret-key',
},
}
{
code: 'supplier-ftp',
type: 'SFTP',
settings: {
host: 'ftp.supplier.com',
username: 'vendure',
passwordSecretCode: 'sftp-password',
// Or for key-based auth:
privateKeySecretCode: 'sftp-private-key',
hostKeyFingerprintSecretCode: 'sftp-host-key',
},
}
hostKeyFingerprintSecretCode must reference the trusted SFTP server host key in OpenSSH SHA256:<base64> format. It is required in production and is checked during the SSH handshake, before authentication or file access.
Stored-value statuses are:
Code-first active means runtime resolution uses the in-memory definition and the displayed database row is inactive.
Changing the provider requires a new non-blank value. For ENV, the value must be an environment-variable name such as SUPPLIER_API_KEY.
The current value is never returned to the browser. The form only knows whether a value exists.
Deletion is blocked when the secret is referenced by a published pipeline, a
nonterminal run snapshot, saved connection, or managed destination. Renaming is
blocked by the same references. The mutation returns NOT_DELETED with the
blocking reference in its message. For a row marked Code-first
active, deleting an unreferenced row removes only the inactive database
fallback; the in-memory definition remains active.
To rotate a secret:
Or, update the secret value directly:
All pipelines using that secret will use the new value immediately.
DATAHUB_MASTER_KEY is not stored by the plugin. Every API server and worker that resolves database INLINE secrets must use the same durable key.
To rotate the key safely:
The Admin API never returns secret values, so the plugin cannot export or automatically re-encrypt unknown plaintext. If the old key is lost or an encrypted row was created with a different key, recover the value from its external authority and replace it. Otherwise clear or delete the unusable row. ENV references are unaffected by master-key rotation.
Define secrets in your Vendure config:
DataHubPlugin.init({
secrets: [
// From environment variable
{ code: 'api-key', provider: 'ENV', value: 'SUPPLIER_API_KEY' },
// Another environment-backed secret
{ code: 'test-key', provider: 'ENV', value: 'TEST_KEY' },
],
})
Code-first secrets:
Code-first INLINE values are never encrypted in TypeScript, JSON, or YAML source. They are rejected in production even when DATAHUB_MASTER_KEY is configured. In non-production they require a valid master key, but the source file still contains plaintext. Use ENV for deployed code-first secrets.
A same-code database row can remain from an older release. The UI marks it as inactive while the code-first definition is active. Removing the code-first definition makes normal database fallback possible on the next startup, so review and delete or deliberately migrate the inactive row before removing the authoritative code-first secret.
{ code: 'api-key', provider: 'ENV', value: 'API_KEY' }
This keeps secrets out of your codebase and allows different values per environment.
ReadDataHubSecret permissionThe plugin is designed to never log secret values. If you’re extending the plugin, maintain this practice.