Skip to main content

Credentials API

The Credentials API allows you to manage account-level credentials in Quave ONE. Credentials store sensitive material your apps and environments need at runtime — Docker registry logins, HTTP basic-auth users, TLS certificates and ACME wildcard configurations.

Make sure to read the Get Started document to understand how the API works.

Note: Mutating endpoints (create, update, delete, set-default, sync) require the Manage Credentials role on the account. Read endpoints (list, get, references) are available to any account member but strip sensitive fields for non-managers.

Create Credential​

To create a new credential, send a POST request to /api/public/v1/credential.

FieldTypeDescriptionRequired
accountIdStringThe account ID to create the credential in.Yes
typeStringOne of: CONTAINER_REGISTRY, BASIC_AUTH, TLS_CERTIFICATE, ACME_WILDCARD, OBJECT_STORAGE.Yes
nameStringA short name for the credential.Yes
descriptionStringOptional description.No
isDefaultBooleanFor Container Registry only — promote as account-wide default.No
providerStringFor ACME Wildcard only — one of: AWS_ROUTE53, AZURE, CLOUDFLARE, GCP, WEBHOOK.Conditional
dataObjectType-specific payload (see examples below).Yes

Container Registry examples​

Static registry​

Use the static provider for Docker Hub, GHCR, GCR, or an internal registry that has stable username/password credentials.

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "ACC_ID",
"type": "CONTAINER_REGISTRY",
"name": "Docker Hub",
"isDefault": true,
"data": {
"registryProvider": "STATIC",
"server": "https://index.docker.io/v1/",
"email": "me@example.com",
"username": "myuser",
"password": "mypassword"
}
}' \
https://api.quave.cloud/api/public/v1/credential

AWS ECR​

Use the AWS ECR provider for private Amazon ECR registries. Quave ONE stores the AWS source credentials encrypted, calls ECR to generate Docker auth material server-side, and refreshes that generated pull-secret token every 6 hours. Do not send a 12-hour aws ecr get-login-password value as a static registry password.

The AWS IAM principal must be able to call ecr:GetAuthorizationToken and read the private repositories used by your app images. server is optional when the registry is the default awsAccountId.dkr.ecr.region.amazonaws.com private registry.

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "ACC_ID",
"type": "CONTAINER_REGISTRY",
"name": "AWS ECR prod",
"isDefault": true,
"data": {
"registryProvider": "AWS_ECR",
"awsAccountId": "123456789012",
"region": "us-east-1",
"server": "123456789012.dkr.ecr.us-east-1.amazonaws.com",
"awsAccessKeyId": "AKIAEXAMPLE",
"awsSecretAccessKey": "aws-secret",
"awsSessionToken": "optional-session-token"
}
}' \
https://api.quave.cloud/api/public/v1/credential

Basic Auth example​

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "ACC_ID",
"type": "BASIC_AUTH",
"name": "Staging gate",
"data": {
"username": "stageuser",
"password": "stagepass"
}
}' \
https://api.quave.cloud/api/public/v1/credential

TLS Certificate example​

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "ACC_ID",
"type": "TLS_CERTIFICATE",
"name": "example.com cert",
"data": {
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"privateKey": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
"ca": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----"
}
}' \
https://api.quave.cloud/api/public/v1/credential

ACME Wildcard example​

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "ACC_ID",
"type": "ACME_WILDCARD",
"name": "*.example.com",
"provider": "CLOUDFLARE",
"data": {
"commonName": "*.example.com",
"altNames": ["example.com"],
"providerConfig": "{\"apiToken\":\"cf-token-here\"}"
}
}' \
https://api.quave.cloud/api/public/v1/credential

Object Storage example​

S3-compatible object storage credentials. The accessKey and secretKey are stored encrypted; bucket is required, while region and endpoint are optional (leave endpoint empty for AWS S3, set it for MinIO, Cloudflare R2, Backblaze B2, etc.). These can be selected in an environment's Backup storage control to send that environment's backups to your own bucket.

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"accountId": "ACC_ID",
"type": "OBJECT_STORAGE",
"name": "Backups bucket",
"data": {
"accessKey": "AKIAEXAMPLE",
"secretKey": "supersecret",
"bucket": "my-backups",
"region": "us-east-1",
"endpoint": "https://s3.example.com"
}
}' \
https://api.quave.cloud/api/public/v1/credential

Response (all types):

{
"credentialId": "CREDENTIAL_ID",
"message": "Credential created successfully"
}

List Credentials​

List all credentials for an account. Optionally filter by type.

curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
'https://api.quave.cloud/api/public/v1/credentials?accountId=ACC_ID'

With type filter:

curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
'https://api.quave.cloud/api/public/v1/credentials?accountId=ACC_ID&type=CONTAINER_REGISTRY'

Response:

{
"credentials": [
{
"credentialId": "CREDENTIAL_ID",
"accountId": "ACC_ID",
"type": "CONTAINER_REGISTRY",
"name": "Docker Hub",
"description": "",
"isDefault": true,
"revision": 1,
"createdAt": "2025-01-01T00:00:00.000Z",
"updatedAt": "2025-01-01T00:00:00.000Z",
"regionSyncStatuses": [
{
"region": "us-east-1",
"status": "SYNCED",
"syncedRevision": 1,
"lastSyncAt": "2025-01-01T00:00:00.000Z"
}
],
"data": {
"registryProvider": "STATIC",
"server": "https://index.docker.io/v1/"
}
},
{
"credentialId": "ECR_CREDENTIAL_ID",
"accountId": "ACC_ID",
"type": "CONTAINER_REGISTRY",
"name": "AWS ECR prod",
"isDefault": false,
"revision": 3,
"refreshStatus": {
"status": "SYNCED",
"lastSuccessAt": "2025-01-01T06:00:00.000Z",
"tokenExpiresAt": "2025-01-01T18:00:00.000Z"
},
"regionSyncStatuses": [
{
"region": "us-east-1",
"status": "SYNCED",
"syncedRevision": 3,
"lastSyncAt": "2025-01-01T06:00:00.000Z"
}
],
"data": {
"registryProvider": "AWS_ECR",
"server": "123456789012.dkr.ecr.us-east-1.amazonaws.com",
"region": "us-east-1",
"awsAccountId": "123456789012"
}
}
]
}
note

Sensitive values (passwords, AWS access keys/session tokens, generated ECR Docker auth, private keys, provider configs) are never returned in list or get responses. Only non-sensitive metadata like registryProvider, server, region, awsAccountId, commonName, and altNames appear in the data field.

Get Credential​

curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
'https://api.quave.cloud/api/public/v1/credential?credentialId=CREDENTIAL_ID'

Returns the same shape as a single item from the list response.

Update Credential​

Send a PATCH request with the fields to update. The type cannot be changed after creation. Omit sensitive data fields to keep their stored values. For AWS ECR, omitting awsAccessKeyId, awsSecretAccessKey, or awsSessionToken keeps the stored encrypted value; send an empty awsSessionToken only when you want to clear an optional temporary session token.

curl -X PATCH \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"credentialId": "CREDENTIAL_ID",
"name": "Docker Hub (updated)",
"data": {
"server": "https://index.docker.io/v1/",
"email": "new@example.com",
"username": "newuser"
}
}' \
https://api.quave.cloud/api/public/v1/credential

Response:

{
"credentialId": "CREDENTIAL_ID",
"message": "Credential updated successfully"
}

Set Default Credential​

Promotes a Container Registry credential to the account-wide default. Apps without an explicit registry selection will use this one.

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "credentialId": "CREDENTIAL_ID" }' \
https://api.quave.cloud/api/public/v1/credential/set-default

Delete Credential​

Deletes a credential. Returns 409 Conflict if the credential is still referenced by apps, hosts, or environments — use List References to check first.

curl -X DELETE \
-H 'Authorization: YOUR_TOKEN' \
'https://api.quave.cloud/api/public/v1/credential?credentialId=CREDENTIAL_ID'

409 response example:

{
"error": "Credential is still in use",
"references": {
"apps": [{ "appId": "...", "name": "my-app", "field": "imagePullAccountSecretId" }],
"envs": [],
"hosts": []
}
}

Sync Credential​

Re-pushes a credential to every active region the account uses. Useful after editing a credential or when a previous sync shows an Error status. For AWS ECR registry credentials, this also generates a fresh ECR Docker auth token and updates refreshStatus.

curl -X POST \
-H 'Authorization: YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{ "credentialId": "CREDENTIAL_ID" }' \
https://api.quave.cloud/api/public/v1/credential/sync

Response:

{
"attempted": 3,
"ok": 3,
"failed": 0
}

List Credential References​

Lists all apps, environments, and hosts that reference a specific credential.

curl -X GET \
-H 'Authorization: YOUR_TOKEN' \
'https://api.quave.cloud/api/public/v1/credential/references?credentialId=CREDENTIAL_ID'

Response:

{
"references": {
"apps": [{ "appId": "...", "name": "my-app", "field": "imagePullAccountSecretId" }],
"envs": [{ "appEnvId": "...", "envName": "production", "field": "basicAuthAccountSecretId" }],
"hosts": [{ "hostname": "example.com", "field": "certificateAccountSecretId" }]
}
}

Managing credentials versus revealing secrets​

Managing a credential does not grant permission to read the secrets stored inside it. Revealing an existing account credential secret or account LLM provider key requires both Manage Credentials and Secrets Access. Secrets Access alone does not grant credential management. A manager without Secrets Access can retain existing masked/encrypted values while editing metadata or replacing a value, but cannot reveal the stored value. Personal keys remain owner-scoped.

Selecting a credential for a workload, testing its connection server-side, or using it during deploy/build does not reveal its plaintext to the caller. Those operations retain their existing permissions. See User Roles for the migration and complete role matrix.