Skip to documentation
API + guides

01Documentation

Credential Sources

Credential sources store the secret material that later gets projected into outbound auth flows.

Sources are created once per team and then referenced by sourceRef from sandbox or template network policy.

The API surface is:

MethodPathPurpose
GET/api/v1/credential-sourcesList sources
POST/api/v1/credential-sourcesCreate a source
GET/api/v1/credential-sources/{name}Get source metadata
PUT/api/v1/credential-sources/{name}Replace a source
DELETE/api/v1/credential-sources/{name}Delete a source

POST creates a new source and returns 409 Conflict when the name already exists. PUT rotates an existing source and returns 404 Not Found when the name does not exist.

Source specs are write-only. Read APIs return metadata such as name, resolverKind, currentVersion, and timestamps, but not the raw secret values.

CLI examples assume you already ran s0 auth login and selected a current team with s0 team use <team-id>.

Resolver Kinds#

Resolver kindKey spec fieldsTypical use
static_headersspec.staticHeaders.valuesBearer tokens and header fragments
static_tls_client_certificatespec.staticTLSClientCertificate.certificatePem, privateKeyPem, optional caPemmTLS client authentication
static_username_passwordspec.staticUsernamePassword.username, passwordUsername/password based outbound auth
static_ssh_private_keyspec.staticSSHPrivateKey.privateKeyPem, optional passphraseSSH transparent proxy upstream authentication

Resolver kind is immutable for a source name. Rotate the secret material within the same resolver kind. To change from one resolver kind to another, create a new source and update the affected bindings to reference that new source.

Storage Backends#

Credential source storage is selected by the platform, not by the credential source API caller.

Sandbox0 supports encrypted PostgreSQL storage and Vault-compatible storage backends. API users keep sending the same write-only spec in both modes. For self-hosted backend configuration, see Self-hosted Configuration.

Create A Source#

POST

/api/v1/credential-sources

go
source, err := client.CreateCredentialSource(ctx, apispec.CredentialSourceWriteRequest{ Name: "github-source", ResolverKind: apispec.CredentialSourceResolverKindStaticHeaders, Spec: apispec.CredentialSourceWriteSpec{ StaticHeaders: apispec.NewOptStaticHeadersSourceSpec(apispec.StaticHeadersSourceSpec{ Values: apispec.NewOptStaticHeadersSourceSpecValues( apispec.StaticHeadersSourceSpecValues{ "token": os.Getenv("GITHUB_TOKEN"), }, ), }), }, }) if err != nil { log.Fatal(err) } fmt.Println(source.Name)

List Sources#

GET

/api/v1/credential-sources

Read APIs return metadata only. Use list to discover source names, resolver kinds, status, and current versions.

go
sources, err := client.ListCredentialSources(ctx) if err != nil { log.Fatal(err) } for _, source := range sources { fmt.Printf("- %s (%s) version=%d\n", source.Name, source.ResolverKind, source.CurrentVersion.Or(0)) }

Get Source Metadata#

GET

/api/v1/credential-sources/{name}

Use get when you know the source name and want the current metadata record without listing everything.

go
source, err := client.GetCredentialSource(ctx, "github-source") if err != nil { log.Fatal(err) } fmt.Printf("%s version=%d status=%s\n", source.Name, source.CurrentVersion.Or(0), source.Status.Or(""))

Update Or Rotate A Source#

Use PUT /api/v1/credential-sources/{name} to replace the source contents while keeping the same source name and resolver kind. Existing bindings continue to point at that source name.

Sources are reusable. Rotate the source once, then keep bindings and credential rules stable by continuing to reference the same sourceRef. Already-claimed sandboxes pick up the new source version through realtime ctld network-cache invalidation. If invalidation delivery is interrupted by a restart or database notification outage, the binding's resolved-material cache TTL remains the fallback consistency bound. The default TTL is 5 minutes, or the binding's cachePolicy.ttl when set.

PUT

/api/v1/credential-sources/{name}

go
source, err := client.UpdateCredentialSource(ctx, "github-source", apispec.CredentialSourceWriteRequest{ ResolverKind: apispec.CredentialSourceResolverKindStaticHeaders, Spec: apispec.CredentialSourceWriteSpec{ StaticHeaders: apispec.NewOptStaticHeadersSourceSpec(apispec.StaticHeadersSourceSpec{ Values: apispec.NewOptStaticHeadersSourceSpecValues( apispec.StaticHeadersSourceSpecValues{ "token": os.Getenv("ROTATED_GITHUB_TOKEN"), }, ), }), }, }) if err != nil { log.Fatal(err) } fmt.Println(source.Name, source.CurrentVersion.Or(0))

Delete A Source#

DELETE

/api/v1/credential-sources/{name}

Delete only succeeds after no sandbox or template credential binding still references the source.

go
_, err := client.DeleteCredentialSource(ctx, "github-source") if err != nil { log.Fatal(err) } fmt.Println("deleted github-source")

Next Steps#