Secrets
Secrets store credentials and other sensitive values your application needs at runtime. Create a named secret, read the current value from an authorized workload, and rotate without rewriting every caller. Listing metadata does not grant the plaintext.
Status: Preview. See the API action reference for the full command list.
At a glance
| Need | Use |
|---|---|
| Create a named value | CreateSecret |
| Read the active value | GetSecretValue without a version selector |
| Read an exact revision | GetSecretValue with versionId |
| Read a rotation candidate | GetSecretValue with versionStage: "pending" |
| Replace the active value | PutSecretValue |
| Inspect metadata without plaintext | DescribeSecret or ListSecrets |
| Rotate and promote a value | RotateSecret |
| Recover an accidental delete | RestoreSecret during the recovery window |
Prerequisites
- A Cloud access JWT from Cloud User Directory, or Cloud access-key credentials for SigV4.
- A policy permitting each required
secrets:<Operation>action. Reading metadata does not grantsecrets:GetSecretValue. - For SigV4, use service code
secretsand the endpoint's region.
Sign in with skippr login. Your session must allow secrets:CreateSecret and secrets:GetSecretValue.
Create a secret
The same create is CLI, Terraform, CDKTF TypeScript, or CDKTF Python. For provider credentials and the shared cloud provider block, see Terraform and CDKTF.
skippr secrets create-secret --name app-database --secret-string replace-this-sample-valuevariable "database_password" {
type = string
sensitive = true
}
resource "cloud_secret" "database" {
name = "app-database"
secret_string = var.database_password
}import { CloudProvider, CloudSecret } from "@skippr/provider-cloud";
const cloud = new CloudProvider(this, "cloud", { region: "eu-central-1" });
new CloudSecret(this, "database", {
name: "app-database",
secretString: process.env.DATABASE_PASSWORD,
provider: cloud,
});import os
from skippr_cdktf import CloudProvider, CloudSecret
cloud = CloudProvider(self, "cloud", region="eu-central-1")
CloudSecret(
self,
"database",
name="app-database",
secret_string=os.environ["DATABASE_PASSWORD"],
provider=cloud,
)Retrieve a secret
Read the current value. Do not run get-secret-value in a shell, CI step, or log collector that records stdout:
skippr secrets get-secret-value --secret-id app-database --version-stage currentThe command returns plaintext in secretString, or base64 in secretBinary. It never returns both. Do not run get-secret-value in a shell, CI step, or log collector that records stdout.
Access and identity
| Fact | Value |
|---|---|
| CLI | skippr secrets <operation> |
| Endpoint | https://secrets.{region}.cloud.skippr.io/ |
| Method | POST |
| Content type | application/json |
| Target | X-Cloud-Target: CloudSecrets.<Operation> |
| Authentication | Bearer JWT, or SigV4 service secrets |
| Authorization | Policy action secrets:<Operation> |
Use a secret name as secretId, or copy the ARN returned by CreateSecret. AWS Secrets Manager ARNs are not accepted.
Operations by task
Store and read values
| Operation | Behavior |
|---|---|
CreateSecret | Creates a name with exactly one of secretString or base64 secretBinary; duplicate names fail |
GetSecretValue | Returns the current version by default, or the requested versionId / versionStage |
PutSecretValue | Appends an immutable version and moves current to it |
Inspect metadata
| Operation | Behavior |
|---|---|
DescribeSecret | Returns name, ARN, timestamps, deletion state, and versionIdsToStages; never the payload |
ListSecrets | Returns names, ARNs, and change times; never payloads |
ListSecrets uses maxResults and opaque nextToken. The service defaults to 100 results and clamps each page to 1–100.
Rotate a value
RotateSecret with a new string or binary value creates a pending version, then promotes it to current. Calling RotateSecret without a value finishes an existing pending rotation. CancelRotateSecret drops the pending stage without promoting it.
This is native rotation; Lambda rotation hooks are not supported. A supplied rotationLambdaArn is ignored and reported as unsupported_never_lambda_rotation.
Delete and restore
DeleteSecret soft-deletes by default. The default recovery window is 7 days, or you can send recoveryWindowInDays. During that window, get and put calls fail until RestoreSecret clears the deletion state.
forceDeleteWithoutRecovery: true permanently removes the secret immediately. It cannot be restored.
Version and stage contract
- Version IDs are immutable UUIDs.
currentis the default stage forGetSecretValue.pendingexists only while a rotation candidate is staged.DescribeSecret.versionIdsToStagesmaps version IDs tocurrentorpending.- A missing version or pending stage returns
ResourceNotFoundException. - A response contains either
secretStringorsecretBinary, based on how that version was stored.
Redaction and safe handling
DescribeSecretandListSecretsare the safe metadata-only calls.GetSecretValuedeliberately returns plaintext or base64 data; clients must keep response bodies out of logs and traces.- Service logs do not log plaintext secret values.
secretStringandsecretBinaryare mutually exclusive. Supplying both, or neither on a value-creating operation, returnsValidationException.
Terraform cloud_secret
| Terraform field or action | Secrets API mapping |
|---|---|
name | Required, create-only identifier; import by name |
secret_string | Required, sensitive, write-only, and create-only |
| Create | CreateSecret |
| Refresh | DescribeSecret; plaintext is not fetched |
| Change name or value | Replacement, not PutSecretValue |
| Destroy | DeleteSecret with force delete |
| Outputs | Computed id and arn |
Protect Terraform state even though the provider marks secret_string sensitive. Use PutSecretValue or RotateSecret for API-managed version changes that should not replace a Terraform resource.
Limits, ignored fields, and errors
| Contract | Preview behavior |
|---|---|
| Default recovery window | 7 days |
| List page | Default 100; clamped to 1–100 |
| Payload choice | Exactly one of secretString or base64 secretBinary |
| Customer-managed keys | Not supported; kmsKeyId reports noop_sse_kms |
| Tags | Not supported; supplied tags report unsupported_never_tags |
Common errors use the shared {"code":"…","message":"…","requestId":"…"} body:
- HTTP 409
ResourceExistsExceptionfor a duplicate name. - HTTP 404
ResourceNotFoundExceptionfor a missing secret, version, or stage. - HTTP 400
InvalidRequestExceptionfor a secret scheduled for deletion or an invalid restore/rotation state. - HTTP 400
ValidationExceptionfor malformed JSON, invalid selectors, or an invalid payload combination. - HTTP 400
DecryptionFailurewhen stored ciphertext cannot be decrypted.
Contracts and related
- CLI and SDKs
- API actions
- Infrastructure resources
- Terraform and CDKTF
- Cloud User Directory
- Functions — resolve an Environment
SecretIdat cold start - Gateway
