Passa al contenuto principale

JWT dei task

Quando l'emissione di JWT è abilitata sul server, un template può generare un token firmato di breve durata per ogni task che avvia. Il token viene esposto al playbook o allo script in esecuzione tramite la variabile d'ambiente SEMAPHORE_JWT e può essere scambiato con credenziali presso qualsiasi sistema che supporti l'autenticazione JWT, come OpenBao o HashiCorp Vault.

Il vantaggio rispetto a un segreto di lunga durata memorizzato nel Key Store è che ogni task riceve un token nuovo che identifica esattamente l'esecuzione del task (progetto, template, id utente) e scade poco dopo il termine del task.

Abilitazione dei JWT su un template​

Nel modulo del template, scorrere fino alla sezione JWT (compare solo quando l'amministratore ha abilitato l'emissione di JWT) e selezionare JWT abilitato.

È possibile configurare le seguenti opzioni per ciascun template:

CampoDescrizione
AudienceUna o più stringhe emesse nel claim aud. Impostare qui l'identificatore o gli identificatori attesi dal sistema a valle (ad esempio l'URL del server OpenBao). Sono supportate fino a 32 voci.
TTLDurata del token espressa come intervallo (30s, 10m, 1h, ...). Se lasciato vuoto, viene utilizzato il valore globale jwt.default_ttl. Il TTL non deve superare il valore globale jwt.max_ttl.

Claim del token​

Ogni token contiene i seguenti claim, sui quali è possibile fare affidamento per concedere l'accesso nel sistema a valle:

ClaimEsempioNote
isshttps://semaphore.example.comConfigurato dall'amministratore.
audhttps://bao.example.comDall'elenco audience del template.
subtask:1234Univoco per ogni esecuzione del task.
iat / nbf / expClaim temporali standard.
jtiIdentificatore univoco del token.
project_id7Progetto a cui appartiene il template.
template_id42Il template che ha generato il task.
user_id67Utente che ha avviato il task (omesso per le esecuzioni pianificate / da integrazione)

Utilizzare questi claim per limitare l'accesso sul lato consumatore. Ad esempio un ruolo OpenBao che accetta solo token con project_id = 7 e un template_id specifico.

Utilizzo del token all'interno di un task​

Semaphore esporta il token come SEMAPHORE_JWT nell'ambiente del processo del task.

#!/usr/bin/env bash

# Bash example
echo "Look at my fancy token: $SEMAPHORE_JWT"
# Ansible example
- name: Read secret from OpenBao KVv2 via JWT auth
ansible.builtin.set_fact:
openbao_secret_value: >-
{{ lookup(
'community.hashi_vault.hashi_vault',
secret='kv/data/semaphore/demo:value',
auth_method='jwt',
url='https://bao.example.com',
role_id=bao_role,
jwt=lookup('ansible.builtin.env', 'SEMAPHORE_JWT')
) }}

Esempio: OpenBao​

La seguente procedura configura OpenBao affinché consideri attendibili i JWT di Semaphore e li scambi con una password dimostrativa. Sostituire semaphore.example.com e bao.example.com con i propri nomi host.

1. Configurare il metodo di autenticazione JWT​

Abilitare il metodo di autenticazione JWT e puntarlo all'endpoint JWKS della propria istanza Semaphore. OpenBao utilizza la chiave pubblica recuperata da lì per verificare ogni token.

bao auth enable jwt

bao write auth/jwt/config \
jwks_url="https://semaphore.example.com/.well-known/jwks.json" \
bound_issuer="https://semaphore.example.com"

2. Definire una policy​

Concedere le autorizzazioni necessarie a un task. L'esempio seguente consente di leggere la credenziale dimostrativa che si trova in kv/data/semaphore/demo:

bao policy write semaphore-demo-policy - <<EOF
path "kv/data/semaphore/demo" {
capabilities = ["read"]
}
EOF

3. Definire un ruolo OpenBao associato a un template​

Un ruolo OpenBao stabilisce quali task di Semaphore possono assumere quale policy. Utilizzare i claim specifici di Semaphore (project_id, template_id, ...) come bound_claims, in modo che solo il template previsto possa utilizzare il ruolo:

bao write auth/jwt/role/semaphore-demo-role - <<EOF
{
"role_type": "jwt",
"user_claim": "sub",
"bound_audiences": "https://bao.example.com",
"bound_claims": {
"project_id": "7",
"template_id": "42"
},
"policies": ["semaphore-demo-policy"],
}
EOF

Limitare sempre ogni ruolo con almeno un claim project_id o template_id. Senza un vincolo, qualsiasi JWT emesso dalla propria istanza Semaphore potrebbe assumere il ruolo.

L'elenco completo dei parametri di configurazione supportati è disponibile qui

4. Configurare il template​

Nel template Semaphore che esegue il playbook di deploy:

  • Selezionare JWT abilitato.
  • Impostare Audience su https://bao.example.com – corrisponde a bound_audiences nel ruolo OpenBao.
  • Facoltativamente impostare TTL su 15m, in modo che il token scada poco dopo il termine del task.

5. Utilizzare il token nel task​

- hosts: localhost
gather_facts: false
tasks:
- name: Read secret from OpenBao KVv2 via JWT auth
ansible.builtin.set_fact:
openbao_secret_value: >-
{{ lookup(
'community.hashi_vault.hashi_vault',
secret='kv/data/semaphore/demo:value',
auth_method='jwt',
url='https://bao.example.com',
role_id='semaphore-demo-role',
jwt=lookup('ansible.builtin.env', 'SEMAPHORE_JWT')
) }}

Il task ora si autentica su OpenBao senza alcun segreto precondiviso 🎉