Skip to content

No OIDC client exists for human login — the API cannot be authenticated to by a person #26

Description

@JohnRDOrazio

Problem

There is no way for a human being to obtain a token for this API.

The MartyrologyAPI Zitadel project contains exactly one app — MartyrologyAPI Backend (384518610325864451), an API app with
API_AUTH_METHOD_TYPE_BASIC. That app is a token validator: the API uses its
client_id/secret to call /oauth/v2/introspect. It has no grantTypes, no
redirect URIs, and cannot perform an authorization-code flow.

So although v0.2.0 ships a working role gate and grant endpoint, and
priest@johnromanodorazio.com holds the admin role plus a superuser tuple,
that user cannot actually authenticate to the API. Zitadel does not issue
Personal Access Tokens for human users — PATs are machine-user only — so there
is no fallback either.

Verified on the live instance: the project's app list returns a single API app,
and introspecting the automation machine user's PAT confirms the introspection
path itself works.

What this blocks

  • A curator signing in and editing an elogium.
  • A licensed reader authenticating to receive unredacted restricted texts.
    Anonymous callers correctly get redacted content, so the licensing gate is
    live but currently unreachable in its allow direction.
  • End-to-end verification of introspection → project-scoped roles claim →
    role gate → OpenFGA, other than by temporarily granting a machine user.

What's needed

An OIDC client in the MartyrologyAPI project capable of user login —
Authorization Code with PKCE, appType Web or Native depending on the answer
to the design questions below.

Open questions, which is why this is an issue rather than a commit:

  1. Who is the client? A dedicated curation UI, an existing CDCF property, or
    a CLI/desktop tool for curators? This determines Web vs Native and the
    redirect URIs.
  2. Does curation get a UI at all, or stay API-only with tokens obtained
    through a generic client?
  3. Audience. The role gate reads
    urn:zitadel:iam:org:project:384518610174869507:roles. A client belonging to
    a different project must request the
    urn:zitadel:iam:org:project:id:384518610174869507:aud scope for that claim
    to appear. Worth deciding deliberately rather than discovering later.
  4. Service accounts. If scripted curation is wanted, a machine user with a
    PAT works today and needs no new client — but note LiturgicalCalendarAPI had
    to add a Zitadel Management API fallback because service accounts using the
    JWT-profile grant receive no roles claim. A PAT-authenticated machine user
    does get roles (verified here); a JWT-profile one may not.

Not a regression

This gap predates v0.2.0 — the project never had a user-facing client. It only
became visible now that there is something for an authenticated user to do.

Provisioning is in CatholicOS/cdcf-infra, auth/setup-zitadel.sh; the
existing create_oidc_api_app helper is parameterised by auth method and is
the natural place to add a login client alongside it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions