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:
- 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.
- Does curation get a UI at all, or stay API-only with tokens obtained
through a generic client?
- 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.
- 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.
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 withAPI_AUTH_METHOD_TYPE_BASIC. That app is a token validator: the API uses itsclient_id/secret to call
/oauth/v2/introspect. It has nograntTypes, noredirect URIs, and cannot perform an authorization-code flow.
So although v0.2.0 ships a working role gate and grant endpoint, and
priest@johnromanodorazio.comholds theadminrole plus asuperusertuple,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
Anonymous callers correctly get redacted content, so the licensing gate is
live but currently unreachable in its allow direction.
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,
appTypeWeb or Native depending on the answerto the design questions below.
Open questions, which is why this is an issue rather than a commit:
a CLI/desktop tool for curators? This determines Web vs Native and the
redirect URIs.
through a generic client?
urn:zitadel:iam:org:project:384518610174869507:roles. A client belonging toa different project must request the
urn:zitadel:iam:org:project:id:384518610174869507:audscope for that claimto appear. Worth deciding deliberately rather than discovering later.
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; theexisting
create_oidc_api_apphelper is parameterised by auth method and isthe natural place to add a login client alongside it.