Secrets
Manage an environment's secrets and the attachments that expose them to an app.
Introduction
A secret is stored once in an environment and attached to the apps that need it, so the two halves of this page are separate: the store belongs to the environment, and an attachment binds one secret to one app. Both halves take environment, and omitted it is production.
An attachment resolves to the environment variable name the value is injected as, which defaults to the secret's own name. That indirection is what lets the same code read HF_TOKEN against a production and a staging credential.
Secrets and plain environment variables share one pod environment and one ceiling of 100 bindings per app. A name already taken by either is rejected with 422, and attaching a secret the app already has returns 409. See Secrets.
List secrets
Returns secret metadata only. Encrypted values are never returned.
Request
environment
stringmin: 1max: 63The environment the secret belongs to. The same name in two environments is two secrets: a write to one never changes the other, and a list cursor is valid only in the environment it came from. Omitted means
production. A name the organization has no live environment under returns404.
limit
integerint32min: 1max: 100default: 20Maximum number of items to return.
cursor
stringOpaque pagination cursor returned by a previous call, as
nextCursoror, on the operations that offer one,prevCursor.
Response
nextCursor
stringnullableCursor for the next page. Null when there are no more items.
data
object[]Array items7 properties each
id
string (uuid)requiredUUID v4
environment
stringrequiredmin: 1max: 63The environment the secret belongs to; set at creation and never changed.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Possible values2 values
metadata
objectnullableOptional opaque metadata associated with the secret.
createdAt
string (date-time)date-time
updatedAt
string (date-time)date-time
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
404 | Resource not found |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Create a secret
Creates a secret in the environment named by environment, production when omitted. A secret of the same name in another environment is a different secret. To copy one into another environment, use POST /v1/secrets/{secretName}/copy. Returns 409 if the name is already in use in the environment, including when a secret of that name is pending_destroy. List only shows active secrets, so a name can appear free while create still conflicts for as long as that row remains. A pending_destroy row is removed, and its name released, by a background sweep once no running worker can still hold the value. There is no deadline on that wait, so a continuously busy app can hold a name for as long as it runs. Recreate-while-deleting may later reuse the pending row with the new value (same name, new ciphertext). An organization whose serverless tenancy is revoked, or has no tenancy receipt at all, returns 403 Forbidden: the per-organization CryptoKey that seals the value is only minted when the tenancy is active. An organization whose tenancy is still being provisioned returns 503 Service Unavailable instead. That state is retryable, not a revocation, and clears once provisioning finishes.
Request
environment
stringmin: 1max: 63The environment the secret belongs to. The same name in two environments is two secrets: a write to one never changes the other, and a list cursor is valid only in the environment it came from. Omitted means
production. A name the organization has no live environment under returns404.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Allowed values2 values
value
stringrequiredmax: 65536Plain-text value. Encrypted at rest by the platform. Capped at 64 KiB, Cloud KMS Encrypt's plaintext ceiling, and the reason the design needs no envelope encryption (ADR-019).
maxLengthis OpenAPI's string-length bound (character count), not a byte limit. Cloud KMS measures UTF-8 bytes, so the server also rejects a value whose UTF-8 encoding exceeds 65536 bytes with422, a rule this schema cannot express alone (multi-byte characters can passmaxLengthand still overrun the KMS limit). Aregistryvalue is a Dockerconfig.json; what that document may contain, and what422refuses, is onSecretType.
metadata
objectnullable
environments
string[]min items: 1max items: 100The environments to create this secret in, one secret per environment, all with this value. Only on a
POST /v1/secret-batchesitem, and only when the request does not nameenvironment; then every item names its own.POST /v1/secretsreturns422when it is set. An environment the organization does not have returns404, and nothing is created.
Response
id
string (uuid)requiredUUID v4
environment
stringrequiredmin: 1max: 63The environment the secret belongs to; set at creation and never changed.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Possible values2 values
metadata
objectnullableOptional opaque metadata associated with the secret.
createdAt
string (date-time)date-time
updatedAt
string (date-time)date-time
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
409 | Resource already exists or the request conflicts with its current state |
413 | The request body exceeds its size limit: 10 MiB on invoke-sync and invoke-async, whose body carries the endpoint's payload, and 1 MiB on the other operations that answer with this response. detail names the limit in bytes.
|
415 | The request body arrived with a Content-Type this operation does not accept. The body was not decoded, so this is not a schema failure. A body of application/json that cannot be parsed returns 400. One that parses and breaks the schema returns 422. A body sent with no Content-Type is the same refusal.
|
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Create many secrets
Creates secrets in the environment named by environment, production when omitted. An item that names its own environments is created once in each of them instead, and then every item must name them and environment must be omitted (422 otherwise). A name may appear in several items as long as no environment receives it twice. The batch is one write: every secret is created, or none are. Returns 409 when any name is already in use in an environment it is sent to, including when a secret of that name is pending_destroy, and errors[] names each conflicting item: its name, or the entry of its environments when the item names them. List only shows active secrets, so a name can appear free while create still conflicts for as long as that row remains. A pending_destroy row is removed, and its name released, by a background sweep once no running worker can still hold the value. There is no deadline on that wait, so a continuously busy app can hold a name for as long as it runs. A name sent twice to one environment is 422. This route does not attach a secret to an app. Attach each one with POST /v1/apps/{appId}/secrets. An organization whose serverless tenancy is revoked, or has no tenancy receipt at all, returns 403 Forbidden: the per-organization CryptoKey that seals the value is only minted when the tenancy is active. An organization whose tenancy is still being provisioned returns 503 Service Unavailable instead. That state is retryable, not a revocation, and clears once provisioning finishes.
Request
environment
stringmin: 1max: 63The environment the secret belongs to. The same name in two environments is two secrets: a write to one never changes the other, and a list cursor is valid only in the environment it came from. Omitted means
production. A name the organization has no live environment under returns404.
secrets
object[]requiredmin items: 1max items: 100Secrets to create. The response lists them in this order, an item once per environment it names. At most 100, and at most 200 secrets written in all (
422beyond that). The request body is still capped at 1 MiB, which is what limits how many large values fit. Each item has the same fields and the same 64 KiB value ceiling asSecretCreate.Array items5 properties each
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Allowed values2 values
value
stringrequiredmax: 65536Plain-text value. Encrypted at rest by the platform. Capped at 64 KiB, Cloud KMS Encrypt's plaintext ceiling, and the reason the design needs no envelope encryption (ADR-019).
maxLengthis OpenAPI's string-length bound (character count), not a byte limit. Cloud KMS measures UTF-8 bytes, so the server also rejects a value whose UTF-8 encoding exceeds 65536 bytes with422, a rule this schema cannot express alone (multi-byte characters can passmaxLengthand still overrun the KMS limit). Aregistryvalue is a Dockerconfig.json; what that document may contain, and what422refuses, is onSecretType.
metadata
objectnullable
environments
string[]min items: 1max items: 100The environments to create this secret in, one secret per environment, all with this value. Only on a
POST /v1/secret-batchesitem, and only when the request does not nameenvironment; then every item names its own.POST /v1/secretsreturns422when it is set. An environment the organization does not have returns404, and nothing is created.
Response
data
object[]requiredArray items7 properties each
id
string (uuid)requiredUUID v4
environment
stringrequiredmin: 1max: 63The environment the secret belongs to; set at creation and never changed.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Possible values2 values
metadata
objectnullableOptional opaque metadata associated with the secret.
createdAt
string (date-time)date-time
updatedAt
string (date-time)date-time
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
409 | Resource already exists or the request conflicts with its current state |
413 | The request body exceeds its size limit: 10 MiB on invoke-sync and invoke-async, whose body carries the endpoint's payload, and 1 MiB on the other operations that answer with this response. detail names the limit in bytes.
|
415 | The request body arrived with a Content-Type this operation does not accept. The body was not decoded, so this is not a schema failure. A body of application/json that cannot be parsed returns 400. One that parses and breaks the schema returns 422. A body sent with no Content-Type is the same refusal.
|
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Update a secret
Re-encrypts the value under the same name (no rename). A secret of the same name in another environment is not changed. Rolls every live deployment that attaches this secret in place so a running worker picks up the new value. activeVersionId does not move. See AppEvent. If a rollout is already in progress when this commits, this change is not guaranteed to land on it. It reaches the worker on a later redeploy instead. A deployment that is not live picks it up on its next deploy for another reason. An organization whose serverless tenancy is revoked, or has no tenancy receipt at all, returns 403 Forbidden: the per-organization CryptoKey that seals the value is only minted when the tenancy is active. An organization whose tenancy is still being provisioned returns 503 Service Unavailable instead. That state is retryable, not a revocation, and clears once provisioning finishes.
Request
secretName
stringrequiredmin: 1max: 128Secret name, unique within an environment (the one named by
environmenton/v1/secrets,productionwhen omitted; the app's on an app route).
environment
stringmin: 1max: 63The environment the secret belongs to. The same name in two environments is two secrets: a write to one never changes the other, and a list cursor is valid only in the environment it came from. Omitted means
production. A name the organization has no live environment under returns404.
Response
id
string (uuid)requiredUUID v4
environment
stringrequiredmin: 1max: 63The environment the secret belongs to; set at creation and never changed.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Possible values2 values
metadata
objectnullableOptional opaque metadata associated with the secret.
createdAt
string (date-time)date-time
updatedAt
string (date-time)date-time
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
413 | The request body exceeds its size limit: 10 MiB on invoke-sync and invoke-async, whose body carries the endpoint's payload, and 1 MiB on the other operations that answer with this response. detail names the limit in bytes.
|
415 | The request body arrived with a Content-Type this operation does not accept. The body was not decoded, so this is not a schema failure. A body of application/json that cannot be parsed returns 400. One that parses and breaks the schema returns 422. A body sent with no Content-Type is the same refusal.
|
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Copy a secret to other environments
Creates a secret in each of targetEnvironments with the name, type, metadata and value of this secret. The value is copied inside the platform and never returned. Each copy is a separate secret: changing or deleting one leaves this secret and the other copies unchanged. The copy is one write: every target gets the secret, or none does. Returns 404 when the environment named by environment holds no active secret of this name, or when any of the environments does not exist. Returns 409 when the name is already in use in a target environment, including when a secret of that name is pending_destroy, and errors[] names each conflicting entry of targetEnvironments. Returns 422 when targetEnvironments includes the secret's own environment. This route does not attach a copy to an app. Attach each one with POST /v1/apps/{appId}/secrets. Like every secret write, it needs an active serverless tenancy: an organization whose tenancy is revoked, or has no tenancy receipt at all, returns 403 Forbidden. An organization whose tenancy is still being provisioned returns 503 Service Unavailable instead. That state is retryable, not a revocation, and clears once provisioning finishes.
Request
secretName
stringrequiredmin: 1max: 128Secret name, unique within an environment (the one named by
environmenton/v1/secrets,productionwhen omitted; the app's on an app route).
environment
stringmin: 1max: 63The environment the secret belongs to. The same name in two environments is two secrets: a write to one never changes the other, and a list cursor is valid only in the environment it came from. Omitted means
production. A name the organization has no live environment under returns404.
targetEnvironments
string[]requiredmin items: 1max items: 100The environments to create a copy in, one secret in each.
Response
data
object[]requiredArray items7 properties each
id
string (uuid)requiredUUID v4
environment
stringrequiredmin: 1max: 63The environment the secret belongs to; set at creation and never changed.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Possible values2 values
metadata
objectnullableOptional opaque metadata associated with the secret.
createdAt
string (date-time)date-time
updatedAt
string (date-time)date-time
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
409 | Resource already exists or the request conflicts with its current state |
413 | The request body exceeds its size limit: 10 MiB on invoke-sync and invoke-async, whose body carries the endpoint's payload, and 1 MiB on the other operations that answer with this response. detail names the limit in bytes.
|
415 | The request body arrived with a Content-Type this operation does not accept. The body was not decoded, so this is not a schema failure. A body of application/json that cannot be parsed returns 400. One that parses and breaks the schema returns 422. A body sent with no Content-Type is the same refusal.
|
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Delete a secret
Soft-deletes a secret: marks the row pending_destroy and bumps revision. This API does not hard-delete the row. Returns 409 while any app still attaches it. Cascade-detach is not performed here. Detach each holder with DELETE .../apps/{id}/secrets/{name} first, which rolls the deployments it names in place. A background sweep removes the row and releases the name once no running worker can still hold the value, rather than assuming every roll a detach started actually landed. A deployment that was not live when detached has nothing to roll until it resumes, so the sweep is the actual backstop, not the detach. While the row remains pending_destroy the name stays reserved in the environment, so create may return 409 (already in use in the environment) even though list no longer shows the secret. Retries on an already-pending name are safe when no attachments remain (204). They still return 409 while attached.
Request
secretName
stringrequiredmin: 1max: 128Secret name, unique within an environment (the one named by
environmenton/v1/secrets,productionwhen omitted; the app's on an app route).
environment
stringmin: 1max: 63The environment the secret belongs to. The same name in two environments is two secrets: a write to one never changes the other, and a list cursor is valid only in the environment it came from. Omitted means
production. A name the organization has no live environment under returns404.
Errors
| Status | When |
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
409 | Resource already exists or the request conflicts with its current state |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
List an app's secrets
Request
appId
stringrequiredmin: 6max: 30Immutable app identifier, unique among the authenticated organization's live apps in one environment. The
environmentquery parameter selects which copy the request addresses.
environment
stringmin: 1max: 63The environment the request addresses. An app id names one copy per environment, so this parameter completes the app's address:
appIdtogether withenvironmentselects the copy. The app list and the app summary are limited to the environment, and an app, build, endpoint, worker, event, usage or attached-secret cursor is valid only in the environment it came from. A metric query that names no app covers the whole organization, and a log query covers this environment; a metric query expanded by app returns only the apps live in this environment. Omitted meansproduction. A name the organization has no live environment under returns404.
limit
integerint32min: 1max: 100default: 20Maximum number of items to return.
cursor
stringOpaque pagination cursor returned by a previous call, as
nextCursoror, on the operations that offer one,prevCursor.
Response
nextCursor
stringnullableCursor for the next page. Null when there are no more items.
data
object[]Array items8 properties each
id
string (uuid)requiredUUID v4
environment
stringrequiredmin: 1max: 63The environment the secret belongs to; set at creation and never changed.
name
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
type
stringrequiredKind of secret.
genericis unsealed into the worker's process environment when the secret is attached to an app.registryis a Dockerconfig.jsonwhose only top-level key isauths. Each entry hasauth, orusernameandpassword, oridentitytoken. A value is422when it namescredHelpersorcredsStore, any other top-level key, an entry key other thanauth,username,passwordoridentitytoken, a key that is not a registry host (a host has a dot or a port, or islocalhost), two keys that normalize to the same host, or a key that appears twice. The platform stores the ciphertext the same way asgenericand keeps the normalized registry hosts beside it. Aregistrysecret cannot be attached to an app (422secret-not-attachable).Possible values2 values
metadata
objectnullableOptional opaque metadata associated with the secret.
createdAt
string (date-time)date-time
updatedAt
string (date-time)date-time
envVarName
stringnullablemin: 1max: 128Resolved environment variable name when it differs from
name. Omitted when the secret name is used. Same reserved-name rules asSecretNamewhen set.
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
404 | Resource not found |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Attach a secret to an app
Records that a secret of the app's environment is attached to the app under a resolved env-var name, and rolls the app's live deployment in place so a running worker picks up the value without waiting for an unrelated deploy. activeVersionId does not move. See AppEvent. If a rollout is already in progress when this commits, this attach is not guaranteed to land on it. It reaches the worker on a later redeploy instead. A deployment that is not live records the attachment only. The next resume reads the attach set fresh. Returns 409 if the secret is already attached, or if another attach would use the same env-var name.
The resolved name (envVarName, or secretName when omitted) must not already exist as a plain environment variable on this app (deployment_configs.key). Only one value can reach the app under a name, so the server rejects the collision with 422 instead of letting one value silently shadow the other. The reverse check applies when setting a plain environment variable.
An app holds at most 100 environment bindings in total, plain environment variables plus attached secrets, the same combined ceiling as create and the single-key env-var route. Attaching when the app is already at that limit returns 422.
A secret can be attached to at most 25 deployments. Rolling every attached deployment is what an update or detach costs, so the ceiling bounds that cost rather than the app side of the binding. Attaching past it returns 422. A registry secret returns 422 secret-not-attachable: a registry login is not an environment variable.
Request
appId
stringrequiredmin: 6max: 30Immutable app identifier, unique among the authenticated organization's live apps in one environment. The
environmentquery parameter selects which copy the request addresses.
environment
stringmin: 1max: 63The environment the request addresses. An app id names one copy per environment, so this parameter completes the app's address:
appIdtogether withenvironmentselects the copy. The app list and the app summary are limited to the environment, and an app, build, endpoint, worker, event, usage or attached-secret cursor is valid only in the environment it came from. A metric query that names no app covers the whole organization, and a log query covers this environment; a metric query expanded by app returns only the apps live in this environment. Omitted meansproduction. A name the organization has no live environment under returns404.
secretName
stringrequiredmin: 1max: 128Secret name, unique within an environment. The shape matches
EnvironmentVariableNameand thesecrets.name/deployment_secrets.env_var_namecolumn CHECKs, one rule for the contract and the schema, because an attached secret is injected as an environment variable under this name, or underenvVarNamewhen that override is set. Names the platform sets in the worker's environment (for exampleRUNTIME,DISABLE_NGINX,MLFLOW_MODELS_WORKERS,UVICORN_HOST) are rejected with422: an accepted collision would replace a platform value the app depends on, be silently dropped in its favour, or reach the app under a name the platform uses for its own value, with no error anywhere. Same guard as plain environment variables. Enforced by the server (not expressible as a pattern here).
envVarName
stringnullablemin: 1max: 128Environment variable name the secret is injected as. Omit or null to use
secretName. The server resolves and stores the final name. Same reserved-name rules asSecretName(422if reserved). The resolved name must also not collide with a plain environment variable key on this app (422).
Errors
| Status | When |
400 | The request was malformed and could not be parsed (e.g. invalid JSON). A well-formed request that fails validation returns 422 instead.
|
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
409 | Resource already exists or the request conflicts with its current state |
413 | The request body exceeds its size limit: 10 MiB on invoke-sync and invoke-async, whose body carries the endpoint's payload, and 1 MiB on the other operations that answer with this response. detail names the limit in bytes.
|
415 | The request body arrived with a Content-Type this operation does not accept. The body was not decoded, so this is not a schema failure. A body of application/json that cannot be parsed returns 400. One that parses and breaks the schema returns 422. A body sent with no Content-Type is the same refusal.
|
422 | The request was well-formed but invalid. A field that broke a rule is unprocessable-entity. Attaching a registry secret is secret-not-attachable. A request that could not be parsed returns 400.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |
Detach a secret from an app
Removes the attachment and rolls the app's live deployment in place so a running worker stops receiving the value. activeVersionId does not move. See AppEvent. If a rollout is already in progress when this commits, this detach is not guaranteed to land on it. The worker stops receiving the value on a later redeploy instead. A deployment that is not live has the removal recorded only. There is nothing to roll until it resumes.
Request
appId
stringrequiredmin: 6max: 30Immutable app identifier, unique among the authenticated organization's live apps in one environment. The
environmentquery parameter selects which copy the request addresses.
secretName
stringrequiredmin: 1max: 128Secret name, unique within an environment (the one named by
environmenton/v1/secrets,productionwhen omitted; the app's on an app route).
environment
stringmin: 1max: 63The environment the request addresses. An app id names one copy per environment, so this parameter completes the app's address:
appIdtogether withenvironmentselects the copy. The app list and the app summary are limited to the environment, and an app, build, endpoint, worker, event, usage or attached-secret cursor is valid only in the environment it came from. A metric query that names no app covers the whole organization, and a log query covers this environment; a metric query expanded by app returns only the apps live in this environment. Omitted meansproduction. A name the organization has no live environment under returns404.
Errors
| Status | When |
401 | Missing or invalid credentials |
403 | Authenticated but not permitted to access this resource |
404 | Resource not found |
422 | The request was well-formed but semantically invalid (e.g. a missing or out-of-range field). A request that could not be parsed returns 400. The errors array carries one entry per offending field.
|
500 | Unexpected server error |
503 | A required service is temporarily unavailable |