SSMSecret
Deployed and supported. The fields and commands described here are stable within version v1alpha1.
apiVersion | ssm.stackngo.io/v1alpha1 |
kind | SSMSecret |
| Applied by | sng apply |
Related sng command | sng 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
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
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):
rotateDayscan be set (non-zero) only iflengthis strictly positive: "rotateDays needs a generated value (length > 0)". A rotation needs a value shape to generate.containscan only containletters,numbers,symbols, each at most once (3 items maximum).- The CLI adds a convenience rule:
sng secret create --contains … --length 0is 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.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
apiVersion string | ssm.stackngo.io/v1alpha1 | ||
kind string | SSMSecret | ||
metadata ObjectMeta | Seul 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.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
length integer | Length 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. | 16 | Maximum: 4096 Minimum: 0 |
rotateDays integer | RotateDays 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 array | Contains 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 string | Description du secret, visible dans sng secret describe. | MaxLength: 1024 Optional: {} | |
materialize boolean | Materialize 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.
| Champ | Description | Défaut | Validation |
|---|---|---|---|
phase string | Phase : Pending (déclaré sans valeur, à poser avec sng secret set), Active ou Error. | Optional: {} | |
version integer | Version courante de la valeur du secret (0 = pas encore de valeur). | Optional: {} | |
nextRotationAt Time | NextRotationAt est la prochaine échéance de rotation. | Optional: {} | |
observedGeneration integer | Dernière version du manifeste prise en compte par la plateforme. | Optional: {} | |
message string | Message : explication de la phase (action attendue en Pending, cause en Error). | Optional: {} | |
conditions Condition array | Conditions du secret (Ready…), avec leur reason et un message lisible. | Optional: {} |
Status and conditions
| Condition | True | False |
|---|---|---|
Ready | The secret is Active in the secrets service: it has a value, Apps can consume it | The secret is declared without a value (Pending) or the declaration failed (Error) |
The condition's reason mirrors the phase (status.phase).
reason / phase | Meaning | Action |
|---|---|---|
Pending | Declared 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 |
Active | The secret has a value (status.version ≥ 1). status.nextRotationAt shows the next rotation if rotateDays > 0 | Nothing |
Error | message: forbidden by the tenant policies (…): a Deny policy in your tenant blocks the platform from managing the secret | Do not detach the platform-managed policy for secrets; check your Deny policies on secret/* |
Error | message describing an invalid parameter (length, classes) | Fix the spec and apply again |
Error | message: … is not enrolled | Platform-side incident: contact support |
Error | message: 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 seconds | If 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
| Symptom | Cause | Fix |
|---|---|---|
sng apply rejects the manifest: "rotateDays needs a generated value (length > 0)" | rotateDays > 0 with length: 0 | Give 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 value | sng secret set NAME --from-file … |
You change length: 16 to length: 32, the value does not change | An existing value is never overwritten | Force 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 replaced | rotateDays > 0: rotation replaces the value regardless of where it came from | Set rotateDays: 0 if the value must stay fixed |
Error "forbidden by the tenant policies" | A tenant Deny policy refuses ssm:declare or ssm:rotate | Remove 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 change | The secret was deleted without its manifest | Restore 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 tenant | materialize: true and another secret of the same name already exists | Rename the SSMSecret |
sng kind delete SSMSecret NAME never finishes | Deleting the secret is refused by a Deny policy on ssm:delete | Remove that refusal, or restore the platform-managed policy for secrets |
See also
- Guides: Declare a secret in a manifest, Create and read a secret, Rotation, Inject a secret into an App
- CLI:
sng secret - Other kinds: App (
envandenvFromfields)