Aller au contenu principal

IAMOIDCTrust

Bêta

Fonctionnalité en cours de déploiement. L'interface décrite ici est celle de la prochaine livraison : elle peut encore évoluer, et n'est pas forcément activée sur votre tenant.

La fédération des pipelines CI est activée progressivement.

apiVersioniam.stackngo.io/v1alpha1
kindIAMOIDCTrust
Appliqué parsng tenant oidc create / delete (ou PUT /v1/iam/oidc-trusts/{name}), pas par sng apply
Commandes liéessng tenant oidc list · get · create · delete, sng tenant policy attach --oidc-trust

À quoi ça sert​

Un IAMOIDCTrust dit à StackNGO d'accepter le jeton OIDC qu'une plateforme de CI remet à chaque job (GitLab id_tokens, GitHub Actions) : un jeton de cet émetteur, dont l'audience, le sub et les claims correspondent, s'échange contre une session de votre tenant sous le principal oidc:<tenant>/<nom>. Aucun secret n'est stocké dans la CI. Le trust n'accorde aucun droit : attachez-lui une policy (sng tenant policy attach POLICY --oidc-trust <nom>). Le parcours complet est dans Déployer sans secret (OIDC).

Exemple minimal​

sng tenant oidc create gitlab-deploy --gitlab-project acme/infra --claim project_id=4242
sng tenant policy attach readwrite --oidc-trust gitlab-deploy

écrit dans l'état désiré du tenant :

gitlab-deploy.yml (écrit par l'API)
apiVersion: iam.stackngo.io/v1alpha1
kind: IAMOIDCTrust
metadata:
name: gitlab-deploy
spec:
issuer: https://gitlab.com
audiences: [https://api.dev.stackngo.fr]
subject: "project_path:acme/infra:ref_type:branch:ref:main"
claims:
project_id: ["4242"]

Le même manifeste s'applique par fichier : sng tenant oidc create gitlab-deploy -f gitlab-deploy.yml (sans préciser de tenant).

Exemple complet commenté​

github-release.yml
apiVersion: iam.stackngo.io/v1alpha1
kind: IAMOIDCTrust
metadata:
name: github-release # label DNS, 63 caractères au plus
spec:
issuer: https://token.actions.githubusercontent.com # iss du jeton, https, sans query ni fragment
audiences: # 1 à 8 ; le aud du jeton doit en contenir une
- https://api.dev.stackngo.fr # défaut de la CLI : l'URL de l'API
subject: "repo:acme/infra:ref:refs/tags/v*" # motif du sub, joker * ; 8 caractères littéraux avant le premier *
claims: # 16 clés max : ET entre clés, OU entre valeurs (jokers permis)
repository_id: ["123456789"] # identifiant stable : protège d'un renommage du dépôt
environment: ["production", "staging"] # l'un ou l'autre
maxSessionDuration: 15m # durée des sessions émises, 5m à 1h (défaut 1h)
sng tenant oidc create github-release -f github-release.yml
sng tenant policy attach ci-publisher --oidc-trust github-release

Équivalent sans fichier : sng tenant oidc create github-release --issuer https://token.actions.githubusercontent.com --subject 'repo:acme/infra:ref:refs/tags/v*' --claim repository_id=123456789 --claim environment=production,staging --max-session 15m.

Champs​

Règles de validation croisées​

Règles du schéma (CEL), reprises par l'API dès sng tenant oidc create :

  • metadata.name est un label DNS de 63 caractères au plus.
  • issuer commence par https:// et ne porte ni ? ni # (ni identifiants dans l'URL) ; 9 à 255 caractères.
  • subject ne commence pas par * et compte au moins 8 caractères littéraux avant le premier * : un trust ne peut pas accepter tous les projets d'une instance.
  • Les clés de claims font 1 à 64 caractères parmi A-Z a-z 0-9 _ . : - et ne peuvent pas être iss, aud, sub, exp, nbf ou iat (couverts par issuer, audiences, subject).
  • maxSessionDuration est une durée comprise entre 5m et 1h.

Règles supplémentaires de l'API :

  • 1 à 8 audiences de 255 caractères au plus ; sans audiences (champ omis ou liste vide), l'API retient l'URL de l'API (https://api.dev.stackngo.fr), l'audience que la CLI demande par défaut. 1 à 16 valeurs par claim, de 255 caractères au plus.
  • 20 trusts au plus par tenant.
  • L'émetteur ne peut pas être un émetteur de la plateforme (son SSO, l'API elle-même, les jetons qu'elle délivre à vos applications) : le trust est refusé dès la demande, 400 issuer "…" is reserved to the platform, et rien n'est enregistré.

IAMOIDCTrust​

IAMOIDCTrust déclare la confiance d'un tenant envers un émetteur OIDC externe (job CI GitLab id_tokens, GitHub Actions). Un jeton de cet émetteur dont l'audience, le sub et les claims correspondent ouvre une session sur la plateforme sous le principal oidc:<tenant>/<nom>. Le trust ne donne aucun droit : ils viennent d'un IAMPolicyBinding qui le cite (subjects.oidcTrusts). Le trust appartient à votre tenant.

ChampDescriptionDéfautValidation
apiVersion stringiam.stackngo.io/v1alpha1
kind stringIAMOIDCTrust
metadata ObjectMetaSeul metadata.name est à renseigner (nom de la ressource dans votre tenant).
spec IAMOIDCTrustSpec
status IAMOIDCTrustStatus

IAMOIDCTrustSpec​

IAMOIDCTrustSpec : émetteur, audiences et motifs (glob '*') que le jeton doit vérifier.

ChampDescriptionDéfautValidation
issuer stringÉmetteur OIDC (iss du jeton), en https, sans query ni fragment.MaxLength: 255
MinLength: 9
audiences string arrayAudiences acceptées : le aud du jeton doit en contenir une.MaxItems: 8
MinItems: 1
items:MaxLength: 255
items:MinLength: 1
subject stringMotif du sub du jeton (glob ''). Il ne commence pas par '' et compte au moins
8 caractères littéraux avant le premier ''. Un sujet GitLab (project_path:) ou
GitHub (repo:) nomme le groupe ou l'organisation (jusqu'au '/') avant tout '
'.
MaxLength: 512
MinLength: 1
claims object (keys:string, values:OIDCClaimValues)Claims supplémentaires : ET entre clés, OU entre valeurs (globs). Les valeurs
booléennes ou numériques du jeton sont comparées en chaîne.
MaxProperties: 16
Optional: {}
maxSessionDuration DurationDurée maximale de la session émise, entre 5m et 1h (défaut 1h).MaxLength: 32
Type: string
Optional: {}
deletionPolicy DeletionPolicyDelete (défaut) : supprimer l'IAMOIDCTrust supprime le trust. Block : la suppression
attend qu'aucun IAMPolicyBinding de votre tenant ne le cite (subjects.oidcTrusts),
puis supprime le trust. Orphan : le trust reste en vigueur.
DeleteEnum: [Block Delete Orphan]
Optional: {}

IAMOIDCTrustStatus​

IAMOIDCTrustStatus : conditions Ready (raisons Registered, Invalid ou IAMUnavailable) et Discovered (lecture réussie ou non de la configuration publique de l'émetteur).

ChampDescriptionDéfautValidation
observedGeneration integerDernière version du manifeste (metadata.generation) prise en compte par la plateforme.
provider ProviderStatusIdentité de la ressource dans le service d'authentification.
lastSyncedAt TimeDate de la dernière prise en compte réussie du manifeste.Optional: {}
conditions Condition arrayConditions décrivant l'état actuel de la ressource (Ready…).
tenant stringTenant auquel le trust appartient.
version integerVersion du trust après la dernière modification enregistrée.

OIDCClaimValues​

Type sous-jacent : string array

OIDCClaimValues : valeurs acceptées pour un claim (OU, globs).

Règles de validation :

  • MaxItems: 16
  • MinItems: 1
  • items:MaxLength: 255
  • items:MinLength: 1

DeletionPolicy​

Type sous-jacent : string

DeletionPolicy indique ce que devient la ressource quand vous supprimez son manifeste : Block bloque la suppression tant que la ressource est encore utilisée, Orphan la conserve, Delete la supprime.

Règles de validation :

  • Enum: [Block Orphan Delete]
ValeurDescription
BlockBloque la suppression tant que la ressource est encore utilisée par une autre.
OrphanSupprime le manifeste mais conserve la ressource créée.
DeleteSupprime la ressource avec le manifeste, sans vérifier son usage.

ProviderStatus​

ProviderStatus identifie la ressource dans le service d'authentification.

ChampDescriptionDéfautValidation
owner stringOrganisation propriétaire de l'objet dans l'annuaire d'identité. Renseigné par la plateforme.
name stringNom de l'objet dans l'annuaire d'identité. Renseigné par la plateforme.
resourceID stringIdentifiant de l'objet dans l'annuaire d'identité. Renseigné par la plateforme.

Les valeurs booléennes ou numériques du jeton (ref_protected: true, project_id: 4242) sont comparées sous forme de chaîne : écrivez ["true"], ["4242"].

Statut et conditions​

ConditionRaisonSignificationAction corrective
Ready=TrueRegisteredle trust est enregistré—
Ready=FalseInvalidla spec est refusée (règle ci-dessus)sng tenant oidc delete puis create avec une spec corrigée
Ready=FalseIAMUnavailableservice d'identité momentanément injoignableréessai automatique
Ready=FalseScopeUnresolvedtenant du trust indéterminéréessai automatique ; si cela dure, contacter le support
Synced=TrueReconciledle trust en vigueur correspond au manifeste—
Discovered=TrueDiscoveredla découverte de l'émetteur (/.well-known/openid-configuration, clés publiques) a réussi—
Discovered=FalseDiscoveryFailedémetteur injoignable ou URL fausse ; le message donne la causevérifier issuer ; la découverte est retentée à chaque échange de jeton

status.tenant donne le tenant du trust, status.version sa version enregistrée. Côté CLI, sng tenant oidc list affiche pending, applied ou deleting, et sng tenant oidc get affiche le résultat de la découverte (discovery: ok, ou discovery: failed: <cause> (retried on use)) dès que le trust a été appliqué. Dans l'API, c'est le champ discovery ({"ok": true} ou {"ok": false, "error": "…"}) de GET /v1/iam/oidc-trusts.

Ce qui se passe à la création et à la suppression​

Création. sng tenant oidc create → PUT /v1/iam/oidc-trusts/<nom> (validation, 202, status: "pending"). Quelques instants plus tard, le trust est enregistré et l'émetteur sondé. Dès Ready=True, un job CI peut ouvrir une session (POST /v1/iam/session avec son jeton et {"tenant": "acme"}).

Mise à jour. sng tenant oidc create refuse un nom existant : supprimez puis recréez. L'API, elle, accepte de remplacer un trust par PUT /v1/iam/oidc-trusts/<nom>.

Ouverture de session. Pour un jeton présenté avec {"tenant": "acme"}, StackNGO retient les trusts d'acme pour l'émetteur du jeton (ou le seul nommé par trust), vérifie sa signature, puis exige qu'un et un seul trust corresponde (audience, sub, chaque claim). La session dure au plus maxSessionDuration, quelle que soit la durée du jeton.

Suppression. sng tenant oidc delete <nom> : plus aucun job ne peut ouvrir de session avec ce trust. Les sessions déjà ouvertes restent valables jusqu'à leur expiration. Les attachements de policy qui citent le trust restent en place, sans effet.

Erreurs fréquentes​

SymptômeCauseCorrection
subject "repo:*": at least 8 literal characters before the first '*'motif trop largepréciser le dépôt : repo:acme/infra:*
claims must not override iss, aud, sub, exp, nbf or iatclaim réservé dans claimsutiliser issuer, audiences, subject
401 invalid identity token à l'échange, jeton pourtant valideaucun trust ne correspond (audience, branche, claim), ou plusieurscomparer iss, aud, sub du jeton (affichés par la CLI) avec sng tenant oidc get ; nommer le trust (STNG_OIDC_TRUST)
Session ouverte, puis 403 forbiddenle trust n'a pas de policy, ou une policy trop étroitesng tenant policy attach POLICY --oidc-trust <nom>
Discovered=False, DiscoveryFailedémetteur injoignable depuis la plateforme, ou URL fausse (barre finale, chemin)vérifier l'URL exacte du iss des jetons
sng tenant oidc create refuse : issuer "…" is reserved to the platform (400)émetteur de la plateformeun trust ne vise que l'émetteur d'une CI externe
discovery: failed: … dans sng tenant oidc getémetteur injoignable ou URL fausse au moment de l'applicationvérifier issuer ; la découverte est retentée à chaque échange de jeton
400 policies: invalid request: at most 20 oidc trusts per tenantlimite atteintesupprimer les trusts inutilisés ; un trust peut accepter plusieurs branches (--ref '*', claims)

Voir aussi​