#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:
| Method | Path | Purpose |
|---|---|---|
GET | /api/v1/credential-sources | List sources |
POST | /api/v1/credential-sources | Create 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 |
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 kind | Key spec fields | Typical use |
|---|---|---|
static_headers | spec.staticHeaders.values | Bearer tokens and header fragments |
static_tls_client_certificate | spec.staticTLSClientCertificate.certificatePem, privateKeyPem, optional caPem | mTLS client authentication |
static_username_password | spec.staticUsernamePassword.username, password | Username/password based outbound auth |
static_ssh_private_key | spec.staticSSHPrivateKey.privateKeyPem, optional passphrase | SSH transparent proxy upstream authentication |
Create A Source#
/api/v1/credential-sources
gosource, 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#
/api/v1/credential-sources
Read APIs return metadata only. Use list to discover source names, resolver kinds, status, and current versions.
gosources, 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#
/api/v1/credential-sources/{name}
Use get when you know the source name and want the current metadata record without listing everything.
gosource, 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. 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.
/api/v1/credential-sources/{name}
gosource, 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#
/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#
Egress Auth
Inject destination-scoped outbound credentials through network policy.
Overview
Define reusable sandbox environments before creating or scaling sandboxes.