Skip to content

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

NeedUse
Create a named valueCreateSecret
Read the active valueGetSecretValue without a version selector
Read an exact revisionGetSecretValue with versionId
Read a rotation candidateGetSecretValue with versionStage: "pending"
Replace the active valuePutSecretValue
Inspect metadata without plaintextDescribeSecret or ListSecrets
Rotate and promote a valueRotateSecret
Recover an accidental deleteRestoreSecret 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 grant secrets:GetSecretValue.
  • For SigV4, use service code secrets and 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.

bash
skippr secrets create-secret --name app-database --secret-string replace-this-sample-value
hcl
variable "database_password" {
  type      = string
  sensitive = true
}

resource "cloud_secret" "database" {
  name          = "app-database"
  secret_string = var.database_password
}
ts
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,
});
python
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:

bash
skippr secrets get-secret-value --secret-id app-database --version-stage current

The 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

FactValue
CLIskippr secrets <operation>
Endpointhttps://secrets.{region}.cloud.skippr.io/
MethodPOST
Content typeapplication/json
TargetX-Cloud-Target: CloudSecrets.<Operation>
AuthenticationBearer JWT, or SigV4 service secrets
AuthorizationPolicy 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

OperationBehavior
CreateSecretCreates a name with exactly one of secretString or base64 secretBinary; duplicate names fail
GetSecretValueReturns the current version by default, or the requested versionId / versionStage
PutSecretValueAppends an immutable version and moves current to it

Inspect metadata

OperationBehavior
DescribeSecretReturns name, ARN, timestamps, deletion state, and versionIdsToStages; never the payload
ListSecretsReturns 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.
  • current is the default stage for GetSecretValue.
  • pending exists only while a rotation candidate is staged.
  • DescribeSecret.versionIdsToStages maps version IDs to current or pending.
  • A missing version or pending stage returns ResourceNotFoundException.
  • A response contains either secretString or secretBinary, based on how that version was stored.

Redaction and safe handling

  • DescribeSecret and ListSecrets are the safe metadata-only calls.
  • GetSecretValue deliberately returns plaintext or base64 data; clients must keep response bodies out of logs and traces.
  • Service logs do not log plaintext secret values.
  • secretString and secretBinary are mutually exclusive. Supplying both, or neither on a value-creating operation, returns ValidationException.

Terraform cloud_secret

Terraform field or actionSecrets API mapping
nameRequired, create-only identifier; import by name
secret_stringRequired, sensitive, write-only, and create-only
CreateCreateSecret
RefreshDescribeSecret; plaintext is not fetched
Change name or valueReplacement, not PutSecretValue
DestroyDeleteSecret with force delete
OutputsComputed 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

ContractPreview behavior
Default recovery window7 days
List pageDefault 100; clamped to 1–100
Payload choiceExactly one of secretString or base64 secretBinary
Customer-managed keysNot supported; kmsKeyId reports noop_sse_kms
TagsNot supported; supplied tags report unsupported_never_tags

Common errors use the shared {"code":"…","message":"…","requestId":"…"} body:

  • HTTP 409 ResourceExistsException for a duplicate name.
  • HTTP 404 ResourceNotFoundException for a missing secret, version, or stage.
  • HTTP 400 InvalidRequestException for a secret scheduled for deletion or an invalid restore/rotation state.
  • HTTP 400 ValidationException for malformed JSON, invalid selectors, or an invalid payload combination.
  • HTTP 400 DecryptionFailure when stored ciphertext cannot be decrypted.