api.auibsal.org/v1. The Society approves each app and decides what it may reach. Members choose whether to allow it, and can disconnect it at any time.
It costs nothing: sign-in is the Supabase OAuth 2.1 server (free on every plan while in beta) and the API runs on the existing apps/api.
How it fits together
1
The app sends the member to sign in
A standard OAuth 2.1 authorization-code flow with PKCE, to
https://fghzahtzgelqnpwdhwjo.supabase.co/auth/v1/oauth/authorize. OpenID Connect discovery is at /auth/v1/.well-known/openid-configuration on the same host.2
The member allows it in the Nexus
Supabase sends them to
nexus.auibsal.org/oauth/consent. The page names the app and lists what it can do. Apps the Society has not approved can only be refused.3
The app gets tokens
It exchanges the code at
/auth/v1/oauth/token for an access token (one hour) and a refresh token.4
The app calls the API as the member
Authorization: Bearer <access token> on https://api.auibsal.org/v1/.... Each request runs as that member, so they can do only what they could do in the Nexus.What keeps it safe
An OAuth access token is an ordinary member token plus aclient_id claim. OAuth scopes (openid, email, profile, phone) only shape the ID token; they do not limit the data. So the limits live in the database, where the app cannot get round them:
- Approved apps only. An app must be listed in Nexus → Administration → Settings → Third-party apps and switched on. A token from any other app sees nothing and cannot call anything.
- Areas. Each listed app gets areas: name and language, the AUIB Literary Journal, events, programs, pages and news. Every table has a restrictive policy that keeps an app inside its areas. A pre-request check does the same for database functions, which skip row policies. Membership records, elections and ballots, the charity ledger and roles are never available to apps.
- Member rules still apply. Inside its areas an app can do only what the member could. Blind review holds: readers get a blind id and the text, never the author.
- The Society’s own endpoints refuse app tokens. Account deletion, exports, signed file links and push tests answer the Nexus only. App tokens work on
/v1alone. - Two-step sign-in. Roles that need it (editors deciding, officers) count only on an
aal2session, so an editor using an app may be asked to finish two-step sign-in first. - Disconnect. Members disconnect an app in Profile and privacy → Connected apps; officers switch an app off for everyone in Settings. Either ends its access at once.
API reference (v1)
Bearer tokens only, never cookies; any origin may call it. Errors are JSON{ "error": "<code>", "detail": ... } with 400 (invalid input), 401 (no or bad token), 403 (not allowed), 404, 409 (conflict) or 500.
The database enforces the call window, the limit per member, the rubric and who may make which move. The API adds no rules of its own.
Setting up an app
1
Turn on the OAuth server (once)
Supabase → Authentication → OAuth Server: on, authorization path
/oauth/consent, dynamic registration off. Authentication → URL Configuration: Site URL https://nexus.auibsal.org. For OpenID Connect ID tokens, switch the project to asymmetric JWT signing keys (Settings → JWT Keys).2
Register the app
Authentication → OAuth Apps → Add: the app’s name, its redirect URLs, and its type: public for apps that run in a browser or on a phone (PKCE, no secret), confidential for apps with a server that can keep a secret. Send the client id (and secret, if any) to the app’s team privately.
3
Approve it in the Nexus
Administration → Settings → Third-party apps → Add an app: the client id, the name, a contact email, and the areas it needs. A Journal team’s tool needs Name and language and AUIB Literary Journal.
What comes next
Ready now: sign-in, the member’s profile and permissions, calls and issues, submitting text, the member’s submissions, reading and scoring, and editorial decisions. Functions in the Journal area (assigning readers, returning for formatting) are also open to approved Journal apps through Supabase directly. Not yet, and what each needs:- File submissions: a
/v1endpoint that issues signed upload links to the private bucket (apps never reach Storage directly). - Publishing issues and pieces:
journal.publishendpoints, plus the editors’ sign-off that apps may publish. - Signing the Publication Agreement: the agreement text first (
TODO(content)in PROGRESS.md). - Telling the app when things change: signed webhooks from the outbox to the app, with a secret per app.
- An OpenAPI description of
/v1, generated from the route schemas. - Custom scopes (for example “read only”), when Supabase supports them; until then the Society’s areas are the limit.