Authentication and access ========================= Adriano has no user accounts of its own. People sign in at your OIDC identity provider; Adriano trusts the access token the provider issues and takes the user's roles from it. CI jobs use separate *push tokens* that can only submit candidates. .. danger:: **The development sign-in must be off in production.** :envvar:`ADRIANO_DEV_SHARED_SECRET` and :envvar:`ADRIANO_DEV_AUTH_ENABLED` exist for local development. With the secret set, anyone who knows it can act as any user, including any reviewer, and approve decisions in their name. Leave both unset in every shared or production environment, and verify it after each deployment (:ref:`verify-dev-auth-off`). How sign-in works ----------------- .. mermaid:: sequenceDiagram actor User participant UI as Adriano web UI participant IdP as OIDC provider participant API as Adriano API User->>UI: opens Adriano, clicks Sign in UI->>IdP: redirect to sign-in User->>IdP: signs in IdP->>UI: redirect back to /auth/callback UI->>IdP: exchange code for tokens IdP-->>UI: access token (audience, roles) UI->>API: request with access token API->>IdP: fetch signing keys (first use only) API->>API: check signature, expiry,
issuer and audience API->>API: map roles to permissions
(catalog file) API-->>UI: data, or 401 / 403 The API never takes part in the sign-in itself. It only checks each request's token. It contacts the identity provider the first time it needs the provider's signing keys, not at start-up, so an unreachable provider never stops Adriano. While the provider is unreachable, requests answer HTTP 503 (``auth_unavailable``). Sessions are kept in browser memory only: reloading the page or opening a new tab asks the user to sign in again (usually without a password prompt, while the provider session lasts). Identity provider contract -------------------------- Register one **public client** for the web UI (authorization code flow with PKCE, no client secret) and configure: Redirect URI ``https:///auth/callback`` (or :envvar:`ADRIANO_OIDC_REDIRECT_URI`). Post-logout redirect URI ``https:///`` (or :envvar:`ADRIANO_OIDC_POST_LOGOUT_REDIRECT_URI`). Web origin Your Adriano address, if the provider restricts browser origins. Access token audience Must contain :envvar:`ADRIANO_OIDC_AUDIENCE` (default ``adr_viewer``). Many providers need an explicit audience mapper for this. Access token roles A list of role names at the path named by :envvar:`ADRIANO_OIDC_ROLES_CLAIM` (default ``roles``; ``realm_access.roles`` for Keycloak realm roles). Signing algorithm RS256. Tokens signed any other way are refused. Endpoints The provider's token and key endpoints must be on the same origin (scheme, host and port) as :envvar:`ADRIANO_OIDC_AUTHORITY`; the browser blocks requests to any other origin. Adriano's content security policy allows the web UI to contact that one origin and nothing else besides Adriano itself. Then set (in ``.env`` with Compose, in the ConfigMap on Kubernetes): .. code-block:: sh ADRIANO_OIDC_AUTHORITY=https://idp.example.com/realms/adr ADRIANO_OIDC_CLIENT_ID=adriano-web ADRIANO_OIDC_AUDIENCE=adr_viewer ADRIANO_OIDC_ROLES_CLAIM=realm_access.roles One authority serves both the API (token validation) and the web UI (sign-in); the client ID, scopes and redirect URIs are described in :doc:`configuration`. Who may do what --------------- Three separate grants control access: ``read`` permission Browse and search. Comes from the ``rbac`` section of the catalog file. ``operate`` permission Start polls and see source problems in detail. Also from ``rbac``. Reviewer Approve or reject records. Comes from ``approval_policy.reviewers`` in the catalog file, by individual user or by role. None of them implies another. A role that ``rbac`` does not list grants nothing. See :doc:`catalog-file` for the syntax. .. tip:: To find a reviewer's ``issuer|subject``, decode one of their access tokens and read the ``iss`` and ``sub`` claims. Push tokens for CI ------------------ Push tokens are shared secrets, one set per source registration. A push token: - lets a CI job submit candidates for that one registration only; - grants no read access and works on no other request; - is never accepted for sign-in, and sign-in tokens are never accepted for pushes. See :doc:`ci-push` to create, hand out and rotate them. What the API answers -------------------- ``401`` with ``not_authenticated`` The request carried no token. ``401`` with ``invalid_token`` or ``token_expired`` The token is wrong for this deployment: bad signature, wrong issuer or audience, or expired. ``403`` with ``permission_required`` The user is signed in, but none of their roles grants the needed permission in ``rbac``. ``503`` with ``auth_unconfigured`` No sign-in method is configured; nobody can sign in. ``503`` with ``auth_unavailable`` The identity provider (or its signing keys) cannot be reached. The health endpoint and the API reference page (``/api/docs``) need no sign-in; they contain no records and no secrets. .. _verify-dev-auth-off: Verifying the development sign-in is off ---------------------------------------- Run these checks after every deployment and after every change to ``.env``. #. The health endpoint reports OIDC only: .. code-block:: sh curl -fsS https://adriano.example.com/healthz ``auth`` must be ``oidc``. ``dev`` or ``oidc+dev`` means :envvar:`ADRIANO_DEV_SHARED_SECRET` is set. #. The development token endpoint does not exist: .. code-block:: sh curl -s -o /dev/null -w '%{http_code}\n' \ -X POST https://adriano.example.com/auth/dev/token The answer must be ``404``. #. The start-up log contains neither ``DEV AUTH ENABLED`` nor ``dev HS256 tokens are accepted``: .. code-block:: sh docker compose logs adriano | grep -i 'dev' #. The sign-in page offers no "Dev sign-in" button. The production web image never contains it, whatever the settings; if you see one, you are not looking at a production build. To turn it off, remove both variables from ``.env`` (and from the shell environment and the environment file), then recreate the container with ``docker compose up -d adriano`` (Kubernetes: ``kubectl rollout restart deployment/adriano``).