Configuration
github-sts se configure via un fichier YAML, des variables d’environnement, ou les deux. Les variables d’environnement remplacent les valeurs du YAML, ce qui fait du YAML la source de vérité pour les valeurs par défaut et des variables d’environnement le bon endroit pour les secrets et les surcharges par environnement.
Configuration YAML
Pointez github-sts vers un fichier de configuration avec GITHUBSTS_CONFIG_PATH :
export GITHUBSTS_CONFIG_PATH=/etc/github-sts/config.yamlConsultez config/github-sts.example.yaml dans le dépôt pour un exemple complet.
Une configuration minimale :
server:
port: 8080
log_level: info
oidc:
allowed_issuers:
- https://token.actions.githubusercontent.com
required_audience: https://sts.example.com
apps:
default:
app_id: 123456
private_key_path: /etc/github-sts/keys/default.pem
org_policy_repo: .github
policy_resolution: org_firstLes niveaux de journal valides sont en minuscules : debug | info | warn | error. oidc.allowed_issuers doit contenir au moins un émetteur ; une liste vide est une erreur de validation.
En production, déployez github-sts avec le chart Helm plutôt que de gérer ce fichier à la main. Consultez Installation du chart Helm.
Pools d’Apps (rotation multi-instances pour la limite de débit)
Un nom d’App logique (apps.<name>) peut être adossé à une seule GitHub App (app_id / private_key / private_key_path, comme ci-dessus) ou à un pool de plusieurs GitHub Apps physiques sous instances:. Chaque instance possède ses propres identifiants de GitHub App, donc son propre quota de limite de débit primaire GitHub indépendant : le plafond effectif d’une App poolée sur le trafic /sts/exchange augmente avec le nombre d’instances. (Cette « instance » est une GitHub App physique, sans rapport avec un réplica du serveur github-sts ; voir Architecture.) Les appelants ne voient jamais que le nom d’App logique dans ?app= ; quelle instance a servi une requête donnée reste interne, et n’apparaît que dans l’étiquette instance des métriques et dans le journal d’audit (voir Métriques).
apps:
checkout:
org_policy_repo: ".github"
instances:
- name: checkout-1 # optionnel ; par défaut app_id si omis
app_id: 111111
private_key_path: "/etc/github-sts/keys/checkout-1.pem"
- name: checkout-2
app_id: 222222
private_key_path: "/etc/github-sts/keys/checkout-2.pem"
- name: checkout-3
app_id: 333333
private_key_path: "/etc/github-sts/keys/checkout-3.pem"
rotation:
strategy: round_robin # round_robin (défaut) | rate_limit_aware
min_remaining_pct: 5 # rate_limit_aware uniquement
max_attempts: 3 # limite le nombre de bascules par requêtePar défaut, github-sts fait tourner les instances d’un pool en round-robin, écarte toute instance actuellement signalée comme inaccessible par la sonde d’accessibilité, et bascule vers l’instance suivante lorsque celle tentée renvoie une erreur réessayable. La rotation avance d’un cran par échange de jeton : c’est l’émission finale du jeton de l’échange qui la fait avancer, et la résolution de la cible et les lectures de politique qui la précèdent commencent sur le membre que cette émission utilisera. Un échange reste donc sur un seul membre, et les émissions se répartissent également dans le pool, quelle que soit sa taille. Les tentatives d’une même requête parcourent des membres consécutifs. Réessayable signifie une erreur réseau/timeout, une réponse 5xx, ou un 403 portant un signal de limite de débit (Retry-After ou X-RateLimit-Remaining: 0) ; un 422 (les autorisations ou dépôts demandés dépassent ce que cette installation accorde) ou tout autre 4xx n’est pas réessayé, car un identifiant différent ne peut pas corriger une incohérence d’autorisations. rotation.max_attempts limite le nombre d’instances tentées par requête (par défaut : taille du pool, plafonnée à 3).
Règles :
instanceset les champs platsapp_id/private_key/private_key_pathsont mutuellement exclusifs sur une App. Une App en forme plate est traitée comme un pool d’une instance.rotationn’a de sens que sur une App poolée (instancesdéfini) : le définir sur une App en forme plate est une erreur de validation, car cela serait autrement du YAML sans aucun effet.- Chaque instance nécessite
app_idet exactement un des deux champsprivate_key/private_key_path. app_iddoit être unique au sein du pool d’une App. Le mêmeapp_idréutilisé entre les pools de deux Apps logiques différentes est autorisé (elles partagent déjà un quota de limite de débit par construction) mais journalise un avertissement au démarrage, car c’est plus souvent un copier-coller erroné qu’une configuration intentionnelle.nameest optionnel et vaut par défautapp_id(converti en chaîne). Comme il devient une valeur d’étiquette Prometheus, il est limité à 100 caractères parmi[a-zA-Z0-9._/-].rotation.strategyvautround_robin(défaut) ourate_limit_aware. Avecrate_limit_aware, chaque requête place en fin d’ordre tout membre dont l’installation pour l’organisation demandée est connue comme étant sousrotation.min_remaining_pct, ou sans requête restante, dans une fenêtre de limite de débit pas encore réinitialisée. Le membre n’est pas retiré : il est encore tenté quand tous les autres membres échouent. Chaque fois qu’une requête le passe sans le tenter,githubsts_app_pool_selection_total{outcome="skipped_rate_limited"}le compte. Quand tous les membres sont bas, ou que rien n’est connu, l’ordre est un simple round-robin.- Les relevés de quota de
rate_limit_awareproviennent uniquement de réponses qui ont consommé une requête : les appels de github-sts faits avec ses propres jetons d’installation et le sondeur de limite de débit. Ils peuvent être en retard sur un épuisement rapide, borné parmetrics.rate_limit_poll_force_counted_interval, faute de quoi la sonde conditionnelle du sondeur deviendrait non fiable pendant toute la durée de vie en cache d’un jeton (~55 minutes), et un compteur dépensé uniquement par des jetons clients n’est jamais visible : la bascule réactive reste le filet de sécurité. Voir la référence des métriques pour l’origine des relevés. github-sts journalise un avertissement au démarrage quandrate_limit_awareest défini alors quemetrics.rate_limit_poll_enabledest désactivé. rotation.min_remaining_pct(plage[0, 100)) ne s’applique qu’àrate_limit_aware. Avec0, seul un membre sans requête restante est placé en fin d’ordre.rotation.max_attemptsvaut par défautmin(len(instances), 3)lorsqu’il est omis ou à0.
Exigence opérationnelle : chaque instance d’un pool doit être installée avec des autorisations et un accès aux dépôts identiques. github-sts traite les membres du pool comme interchangeables ; il ne vérifie pas actuellement qu’ils le sont réellement, donc une instance mal configurée ne se manifeste que par un 422 intermittent ou un échec d’accessibilité, sur la fraction des requêtes qui tombent dessus.
TLS natif et mTLS
github-sts peut servir HTTPS directement, mais ne gère pas le cycle de vie des certificats. Le TLS est activé implicitement lorsque vous fournissez à la fois un certificat et une clé ; fournissez un bundle de CA clientes pour exiger et vérifier les certificats clients (mTLS) :
server:
port: 8443
tls:
cert_file: /etc/github-sts/tls/tls.crt
key_file: /etc/github-sts/tls/tls.key
# Optionnel : activer le mTLS en faisant confiance à un bundle de CA clientes.
# client_ca_file: /etc/github-sts/tls/client-ca.crt
# Optionnel : imposer TLS 1.3 uniquement (par défaut : "1.2" — TLS 1.2 et supérieur).
# min_version: "1.3"
# Optionnel : restreindre aux suites de chiffrement TLS 1.2 spécifiées (noms IANA).
# Omettez pour utiliser les valeurs par défaut de Go. Ne peut pas être défini avec min_version "1.3".
# cipher_suites:
# - TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
# - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
# - TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
# Optionnel : sonder les fichiers cert/clé à intervalle régulier et les recharger
# lorsqu'ils changent, permettant une rotation des certificats sans interruption.
# "0" désactive le sondage (par défaut). Sans cela, la rotation nécessite un redémarrage.
# reload_interval: 1hRègles :
cert_fileetkey_filedoivent être définies ensemble. Définir l’une sans l’autre est une erreur de validation.client_ca_filerequiertcert_fileetkey_file.min_versionaccepte"1.2"(par défaut) ou"1.3".cipher_suitesaccepte des noms IANA. Seules les suites non-insécures de la bibliothèque standard de Go sont valides. Définir des suites de chiffrement avecmin_version: "1.3"est également une erreur de validation.reload_intervalactive un sondage périodique des fichiers de certificat et de clé. Lorsque les fichiers changent, ils sont rechargés sans redémarrer le processus. Requiertcert_fileetkey_file.- La vérification des clients utilise
RequireAndVerifyClientCertlorsqueclient_ca_fileest défini.
Le modèle de déploiement recommandé consiste à terminer le TLS au niveau de l’ingress/Gateway de la plateforme lorsqu’il est disponible, et à utiliser le TLS natif pour les déploiements autonomes ou lors du re-chiffrement du trafic Gateway→backend (par ex. BackendTLSPolicy de Gateway API). Consultez Modèle de sécurité pour les recommandations sur les frontières de confiance.
Politiques de confiance
Les politiques de confiance sont des fichiers YAML stockés dans le dépôt cible qui définissent quelles identités OIDC peuvent demander des jetons et avec quelles autorisations.
Emplacement : .github/sts/{app_name}/{identity}.sts.yaml
Le chemin de base est configurable via GITHUBSTS_POLICY_BASE_PATH (par défaut .github/sts).
Consultez le guide Politiques de confiance pour le schéma complet de politique, les exemples et les conseils de sécurité.