Skip to main content

SSMSecret

Available

Deployed and supported. The fields and commands described here are stable within version v1alpha1.

apiVersionssm.stackngo.io/v1alpha1
kindSSMSecret
Applied bysng apply
Related sng commandsng secret create NAME generates and applies this manifest; sng secret set, get, describe act on the value

What it is for​

An SSMSecret declares that a secret exists in your tenant and how its value is produced: length, character classes, rotation. The value itself never appears in the manifest: either the secrets server generates it at creation, or you set it afterwards with sng secret set.

This is the declarative way to manage your secrets: the manifest is versioned with the rest of your tenant, deleting the manifest deletes the secret, and an existing value is never overwritten by applying the manifest again.

Minimal example​

db-password.yml
apiVersion: ssm.stackngo.io/v1alpha1
kind: SSMSecret
metadata:
name: db-password
spec:
length: 16

Single-command equivalent: sng secret create db-password.

When applied, the server generates a 16-character value (letters, digits, symbols). Read it with sng secret get db-password.

Complete annotated example​

db-password.yml
apiVersion: ssm.stackngo.io/v1alpha1
kind: SSMSecret
metadata:
name: db-password # secret name: lowercase, digits, . _ - (max 128)
spec:
length: 24 # length of the generated value; 0 = declared empty,
# you set the value with sng secret set (default 16)
rotateDays: 30 # new value generated every 30 days; 0 = never.
# Requires length > 0. Rotation replaces the value
# even if you set it by hand.
contains: [letters, numbers] # character classes: letters, numbers, symbols;
# empty = all. At least one character from each class.
description: "Mot de passe Postgres de l'app shop" # visible in sng secret describe
materialize: false # true: also usable by your static sites (CDNSite)
# and notification channels, even if no App reads it

Equivalent: sng secret create db-password --length 24 --rotation 30 --contains letters,numbers --description "Mot de passe Postgres de l'app shop". materialize has no flag: add it to the manifest (sng secret create … --dry-run).

Fields​

Cross-field validation rules (enforced at sng apply time):

  • rotateDays can be set (non-zero) only if length is strictly positive: "rotateDays needs a generated value (length > 0)". A rotation needs a value shape to generate.
  • contains can only contain letters, numbers, symbols, each at most once (3 items maximum).
  • The CLI adds a convenience rule: sng secret create --contains … --length 0 is rejected, because the classes only matter for a generated value.

SSMSecret​

SSMSecret déclare un secret du service de secrets : son existence et la façon dont sa valeur est produite, jamais la valeur elle-même.

ChampDescriptionDéfautValidation
apiVersion stringssm.stackngo.io/v1alpha1
kind stringSSMSecret
metadata ObjectMetaSeul metadata.name est à renseigner (nom de la ressource dans votre tenant).
spec SSMSecretSpec
status SSMSecretStatus

SSMSecretSpec​

SSMSecretSpec déclare un secret de votre tenant.

Le manifeste dit que le secret existe et comment sa valeur est produite ; la valeur elle-même n'apparaît jamais dans le manifeste : elle reste chiffrée dans le service de secrets.

ChampDescriptionDéfautValidation
length integerLength de la valeur générée. 0 = secret déclaré vide : l'utilisateur pose la
valeur (sng secret set). Une valeur existante n'est jamais écrasée à la création.
16Maximum: 4096
Minimum: 0
rotateDays integerRotateDays renouvelle la valeur tous les N jours (0 = pas de rotation). La
rotation remplace la valeur quelle que soit son origine.
Maximum: 3650
Minimum: 0
Optional: {}
contains string arrayContains liste les classes de caractères de la valeur générée ; vide = toutes.
Au moins un caractère de chaque classe retenue.
MaxItems: 3
items:Enum: [letters numbers symbols]
Optional: {}
description stringDescription du secret, visible dans sng secret describe.MaxLength: 1024
Optional: {}
materialize booleanMaterialize rend le secret utilisable par les autres ressources du tenant (site
statique, canal de notification), même si aucune application ne le lit. La valeur
suit chaque nouvelle version, rotation comprise. Sans ce champ, le secret n'est
mis à disposition que des applications qui le référencent.
Optional: {}

SSMSecretStatus​

SSMSecretStatus reflète l'état du secret dans le service de secrets.

ChampDescriptionDéfautValidation
phase stringPhase : Pending (déclaré sans valeur, à poser avec sng secret set), Active ou Error.Optional: {}
version integerVersion courante de la valeur du secret (0 = pas encore de valeur).Optional: {}
nextRotationAt TimeNextRotationAt est la prochaine échéance de rotation.Optional: {}
observedGeneration integerDernière version du manifeste prise en compte par la plateforme.Optional: {}
message stringMessage : explication de la phase (action attendue en Pending, cause en Error).Optional: {}
conditions Condition arrayConditions du secret (Ready…), avec leur reason et un message lisible.Optional: {}

Status and conditions​

ConditionTrueFalse
ReadyThe secret is Active in the secrets service: it has a value, Apps can consume itThe secret is declared without a value (Pending) or the declaration failed (Error)

The condition's reason mirrors the phase (status.phase).

reason / phaseMeaningAction
PendingDeclared with length: 0, no value yet; or the tenant was just created and its session has not been granted yet (message: waiting for the tenant session)Set the value: sng secret set NAME. The status goes back to Active within 10 minutes. For a new tenant, just wait
ActiveThe secret has a value (status.version ≥ 1). status.nextRotationAt shows the next rotation if rotateDays > 0Nothing
Errormessage: forbidden by the tenant policies (…): a Deny policy in your tenant blocks the platform from managing the secretDo not detach the platform-managed policy for secrets; check your Deny policies on secret/*
Errormessage describing an invalid parameter (length, classes)Fix the spec and apply again
Errormessage: … is not enrolledPlatform-side incident: contact support
Errormessage: the value could not be made available to the other resources of the tenant: materialize: true, and another secret of the same name already exists in your tenant (it is never overwritten); or a transient failure, retried every 30 secondsIf the message persists, rename the SSMSecret

Other status fields: version (current version, 0 = no value yet), nextRotationAt (next rotation), observedGeneration, message. sng kind get SSMSecret NAME shows them as comments below the manifest.

What happens when you apply​

Creation. If the secret does not exist, it is created; if length > 0 and it has no value, a value is generated and saved as version 1. If a value already exists (set with sng secret set before or after the declaration), it is kept as is. The rotation policy is the manifest's.

Update. Changing length or contains on a secret that already has a value does not change that value: these fields only describe the first generation and future rotations. Changing rotateDays updates the rotation policy (0 disarms it). Setting length to 0 disarms a rotation previously set by the manifest.

Timing. A Pending secret that receives its value goes back to Active within 10 minutes. After a rotation, the new version shows up in the status about one minute after the due time.

materialize: true. As soon as the secret has a value, it becomes usable, under the same name and with the same keys, by the tenant resources that read a secret without being an App: credentialsSecretRef and tlsSecretRef of a CDNSite, urlSecretRef and webhookSecretRef of a NotificationChannel. Each new version, rotation included, reaches them within 5 minutes. Without this field, the secret is only made available to the Apps that reference it. See Declare a secret by manifest.

What happens when you delete​

sng kind delete SSMSecret NAME deletes the secret: it is no longer listed or readable, and the Apps that use it can no longer read it. Its versions are not erased: sng secret restore NAME puts it back into service with all its versions, and a later sng secret set NAME recreates it under the same name, continuing the version numbering (see Versions and restore).

Common errors​

SymptomCauseFix
sng apply rejects the manifest: "rotateDays needs a generated value (length > 0)"rotateDays > 0 with length: 0Give a length, or remove rotateDays
The status stays Pending with "declared without value: set it with sng secret set NAME"length: 0: the secret is waiting for its valuesng secret set NAME --from-file …
You change length: 16 to length: 32, the value does not changeAn existing value is never overwrittenForce a new value: sng secret rotate NAME --length 32, or wait for the scheduled rotation
You had set a value by hand, and it was replacedrotateDays > 0: rotation replaces the value regardless of where it came fromSet rotateDays: 0 if the value must stay fixed
Error "forbidden by the tenant policies"A tenant Deny policy refuses ssm:declare or ssm:rotateRemove that refusal, or restore the platform-managed policy for secrets
The manifest reapplied after a sng secret delete NAME never becomes Active again and the status does not changeThe secret was deleted without its manifestRestore it with sng secret restore NAME (or recreate a value with sng secret set NAME), then apply again
Error: the value could not be made available to the other resources of the tenantmaterialize: true and another secret of the same name already existsRename the SSMSecret
sng kind delete SSMSecret NAME never finishesDeleting the secret is refused by a Deny policy on ssm:deleteRemove that refusal, or restore the platform-managed policy for secrets

See also​