baptistegh opened a new pull request, #75913:
URL: https://github.com/apache/airflow/pull/75913

   
   Command-line clients can only log in to the Keycloak auth manager with a 
username and password, which doesn't work for users who sign in through SSO or 
with a second factor. This lets them log in through Keycloak in their browser, 
and refresh the CLI token's short-lived Keycloak tokens. Keycloak advertises 
both through the CLI login discovery route from #75672.
   
   This is the provider side only. The airflowctl side (`auth login --sso`) 
follows in #75804, which also shows the whole flow end to end.
   
   related: #75560
   
   ### Changes
   
   - `get_cli_login_methods()` always advertises `password` and 
`refresh_token`. It adds `authorization_code` with `S256` only when 
`[keycloak_auth_manager] cli_authorization_code_enabled` is on (default 
`False`).
   - `/auth/token/cli` gets its own body: `password` (the default, so existing 
clients are unaffected), `refresh_token` or `authorization_code`. 
`client_credentials` and `jwt-bearer` stay on `/auth/token` only.
   - `GET /auth/login/cli` requires a loopback `redirect_uri` 
(`http://127.0.0.1` or `[::1]`, any port, path `/callback`) and an `S256` 
challenge, then forwards both to Keycloak. Airflow enforces PKCE here rather 
than on the Keycloak client, because the web login doesn't use it.
   - **Refresh:** the new token keeps the expiry of the old one, so a refresh 
never extends a CLI session. Expired and revoked tokens are refused through the 
auth manager's own `get_user_from_token`.
   - Keycloak clients with "Use Refresh Tokens" turned off are handled the same 
way as in #75871.
   - Bumps `python-keycloak>=6.0.0` for PKCE support.
   - On Airflow versions without CLI login discovery, the new hook is never 
called, so no version gate is needed.
   
   ### Trying it without airflowctl
   
   With `cli_authorization_code_enabled = True` and `http://127.0.0.1/callback` 
in the Keycloak client's valid redirect URIs:
   
   ```bash
   # 1. Discover the login methods
   curl "${AIRFLOW_URL}/api/v2/auth/cli/metadata"
   
   # 2. Open in a browser. After login, Keycloak redirects to
   #    http://127.0.0.1:8765/callback?code=...&state=xyz (nothing needs to 
listen; copy the code from the address bar)
   VERIFIER=$(openssl rand -base64 48 | tr -d '=+/\n' | cut -c1-64)
   CHALLENGE=$(printf '%s' "$VERIFIER" | openssl dgst -sha256 -binary | openssl 
base64 | tr '+/' '-_' | tr -d '=\n')
   echo 
"${AIRFLOW_URL}/auth/login/cli?redirect_uri=http://127.0.0.1:8765/callback&state=xyz&code_challenge=${CHALLENGE}&code_challenge_method=S256";
   
   # 3. Exchange the code for a CLI token
   curl -X POST "${AIRFLOW_URL}/auth/token/cli" -H 'Content-Type: 
application/json' \
     -d "{\"grant_type\": \"authorization_code\", \"code\": \"<code>\", 
\"code_verifier\": \"${VERIFIER}\", \"redirect_uri\": 
\"http://127.0.0.1:8765/callback\"}";
   
   # 4. Refresh it
   curl -X POST "${AIRFLOW_URL}/auth/token/cli" -H 'Content-Type: 
application/json' \
     -d '{"grant_type": "refresh_token", "token": "<CLI token>"}'
   ```
   
   ---
   
   ##### Was generative AI tooling used to co-author this PR?
   
   - [X] Yes (please specify the tool below)
   
   Generated-by: Claude Code (Opus 5.5) following [the 
guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#gen-ai-assisted-contributions)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to