Authentification et session
La CLI tk-ota-push implémente un flux d'authentification Web-to-CLI sécurisé par PKCE (Proof Key for Code Exchange, S256) dans AuthManager (lib/src/cli/auth/auth_manager.dart) et persiste les identifiants localement via SessionManager (lib/src/cli/auth/session_manager.dart). Pour les environnements CI/CD sans navigateur, la variable d'environnement OTA_API_KEY permet d'outrepasser le flux interactif.
1. Connexion interactive (tk-ota-push login)
# Connexion standard (lit web_console_url dans shorebird.yaml ou http://localhost:3000)
tk-ota-push login
# Connexion en spécifiant explicitement l'URL de la Console Web
tk-ota-push login --web-url https://console.ota.exemple.org
Cascade de résolution de l'URL Web
Lors de l'appel à tk-ota-push login, l'URL du portail Web est résolue dans cet ordre :
- Flag
--web-url - Champ
web_console_urldansshorebird.yaml - Variable d'environnement
OTA_WEB_CONSOLE_URL - Défaut :
http://localhost:3000
Séquence détaillée du flux PKCE (AuthManager.login)
- Initialisation : La CLI démarre un écouteur local sécurisé (
http://127.0.0.1:<port>). - Connexion Web : La CLI ouvre votre navigateur sur la page
/cli/loginde la Console TkushPatch. - Échange de jeton : Après validation de vos identifiants, un jeton sécurisé est transmis à l'écouteur local.
- Persistance sécurisée : Les identifiants de session sont enregistrés localement dans
~/.tk_ota_push/credentials.json.
Paramètres exacts de la requête d'autorisation initiale ouverte dans le navigateur :
callback_url:http://127.0.0.1:<port>/callbackstate: chaîne aléatoire sécurisée de 32 caractères (Random.secure())code_challenge: condensat SHA-256 encodé en Base64URL sans padding=code_challenge_method:S256device_name:Platform.localHostnamecli_version:0.2.0
Le délai d'attente maximal (timeout) avant expiration de la tentative de connexion est de 3 minutes.
2. Échange et rafraîchissement des jetons
Échange initial (/api/cli/token/exchange)
Une fois le code reçu sur /callback, la CLI effectue une requête POST vers <webConsoleUrl>/api/cli/token/exchange :
{
"code": "<code_ephemere>",
"code_verifier": "<verifier_64_caracteres>"
}
Rafraîchissement automatique (ensureFreshToken)
Avant chaque commande release, patch, promote ou symbols, si aucun OTA_API_KEY n'est défini dans l'environnement, la CLI charge la session locale et vérifie credentials.isExpired :
- Un jeton est considéré comme expiré 30 secondes avant son horodatage
expires_at(DateTime.now().isAfter(expiresAt.subtract(const Duration(seconds: 30)))). - S'il est expiré et qu'un
refreshTokenest disponible,AuthManager.ensureFreshTokenappelletokenRefreshUrl(ou<webConsoleUrl>/api/cli/token/refresh) enPOST:
{
"refresh_token": "<refresh_token>",
"tenant_id": "<tenant_id>"
}
Si le serveur répond 200 OK, la nouvelle session est immédiatement persistée dans ~/.tk_ota_push/credentials.json.
3. Stockage de la session locale (SessionManager)
Le fichier de session est enregistré dans :
- macOS / Linux :
$HOME/.tk_ota_push/credentials.json(avec permissions restreintes viachmod 600) - Windows :
%USERPROFILE%\.tk_ota_push\credentials.json
Structure JSON persistée par CliCredentials.toJson() :
{
"access_token": "<jwt_access_token>",
"refresh_token": "<jwt_refresh_token>",
"expires_at": "2026-11-09T14:30:00.000Z",
"tenant_id": "sara-money",
"username": "alice.dev@saramoney.cm",
"sub": "user-uuid-999",
"roles": ["RELEASE_DEVELOPER", "SECURITY_OFFICER"],
"token_refresh_url": "http://localhost:3000/api/cli/token/refresh",
"web_console_url": "http://localhost:3000"
}
4. Vérification de la session (tk-ota-push whoami)
La commande whoami lit ~/.tk_ota_push/credentials.json et affiche les informations d'identité sans effectuer d'appel réseau :
tk-ota-push whoami
Sortie :
Connecté en tant que : alice.dev@saramoney.cm
Tenant ID : sara-money
Subject (UUID) : user-uuid-999
Rôles : RELEASE_DEVELOPER, SECURITY_OFFICER
Expiration jeton : 2026-11-09 15:30:00.000
5. Authentification CI/CD sans navigateur (OTA_API_KEY)
Sur un serveur d'intégration continue (GitHub Actions, GitLab CI, Jenkins, Bitbucket Pipelines), n'exécutez pas tk-ota-push login. Injectez directement le jeton d'accès dans la variable d'environnement OTA_API_KEY :
export OTA_API_KEY="<VOTRE_JETON_CI_OU_BEARER>"
export OTA_SERVER_URL="https://ota.exemple.org"
export OTA_TENANT_ID="sara-money"
tk-ota-push release --platform android --artifact aab
Dans OtaApiClient, si apiKey est non vide, l'en-tête HTTP suivant est ajouté à chaque requête vers /api/admin/v1/* :
Authorization: Bearer <OTA_API_KEY>
6. Déconnexion (tk-ota-push logout)
Pour révoquer localement la session et supprimer le fichier ~/.tk_ota_push/credentials.json :
tk-ota-push logout
Sorties possibles :
Session supprimée avec succès.(si une session existait)Déjà déconnecté.(si aucun fichiercredentials.jsonn'était présent)