a13n
Build AI agents and run them on cloud.
Citizen portal demo — AI agent delegation, FGA authorization, and MCP tool access.
Developer toolsTypeScript · JavaScriptGitHub @tobyallenOnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
No updates detected yet. GitHub releases will appear here.
Owners of public repositories under a personal GitHub account can sign in to verify ownership and manage the introduction themselves. No administrator approval is needed.
Sign in, generate a verification file, and commit it to this repository’s default branch within 30 minutes. Files on other branches or forks do not count. Then check the file below to manage the project without administrator approval. Keep the file to retain your access.
If needed, you will go to sign-in. After signing in, return here and press your chosen verification button again.
Run /nomorevibe verify in your project folder to verify ownership and manage the introduction yourself.
Verify in one minuteAsk about other verification options
The maker's introduction consists of the line above. Read the repository README for more details. Repository README ↗
Loading the full README.
Read the full README ↗SmartGov Citizen Portal — the workshop demo for apidays Australia 2026's session on securing AI agents and MCP tool calls with Auth0 and OpenFGA. A citizen signs up, talks to an AI assistant about their own tax record, and can grant (and revoke) the assistant delegated access via Auth0 FGA. See the write-up for the reasoning behind the authorisation model.
@auth0/nextjs-auth0)fga-model.fgasrc/app/api/mcp)Nothing in this repo is tied to a specific Auth0 tenant, FGA store, or Firebase project — every deployment creates its own. Rough order:
Auth0 tenant — create a free tenant if you don't have one.
APP_BASE_URL to wherever you're running it (e.g. http://localhost:3000 locally, your Vercel URL in production), then add that as an Allowed Callback/Logout URL.APP_API_AUDIENCE.resource_server-type client for the OBO token exchange (OBO_BACKEND_CLIENT_ID/SECRET), with token_exchange.allow_any_profile_of_type enabled — this is deliberately not the same client as the citizen portal.citizen and caseworker Roles under User Management → Roles, and note both role IDs.auth0-actions/assign-persona-role.js and auth0-actions/provision-citizen-record.js as post-login Actions, both gated to run once on first login only. assign-persona-role.js needs Action Secrets DOMAIN/CLIENT_ID/CLIENT_SECRET (a Management API client with update:users access) plus CITIZEN_ROLE_ID/CASEWORKER_ROLE_ID. provision-citizen-record.js needs PROVISIONING_SYNC_URL (your deployed app's /api/provisioning/sync URL) and PROVISIONING_SYNC_SECRET (matching the app's own env var of the same name). Both Actions read the persona the visitor chose on the landing page (?persona=citizen/?persona=caseworker on /auth/login, forwarded to /authorize and read from event.request.query.persona) — deliberately on post-login, not post-user-registration, since only post-login is synchronous/blocking with a full api object; post-user-registration is documented as asynchronous and can't reliably finish before the signup redirect completes.auth0 roles create --name citizen, auth0 roles create --name caseworker, then auth0 actions create --name "Assign Persona Role" --trigger post-login --code "$(cat auth0-actions/assign-persona-role.js)" --dependency "auth0=4.37.1" --secret "CITIZEN_ROLE_ID=<id>" --secret "CASEWORKER_ROLE_ID=<id>" --secret "DOMAIN=<your-domain>" --secret "CLIENT_ID=<mgmt-client-id>" --secret "CLIENT_SECRET=<mgmt-client-secret>" (repeat similarly for provision-citizen-record.js), then deploy and bind each via and attaching them to the Login flow.Auth0 FGA — create a store at dashboard.fga.dev, write the model from fga-model.fga, and create an API client for it. Note the store ID, model ID, and client credentials.
Firebase — create a project at console.firebase.google.com, enable Firestore, and deploy firestore.rules (firebase deploy --only firestore:rules, once you've run firebase init and linked the project). Generate a service account key (Project Settings → Service Accounts → Generate new private key) for the FIREBASE_* env vars — this is the Admin SDK, server-side only; the app has no client-side Firebase Auth/Firestore code yet, so there's no separate client-side Firebase config to set up.
Vercel AI Gateway — get an API key from your Vercel account. No AWS credentials needed in this app; the Gateway calls Bedrock's Nova Pro model (amazon/nova-pro) using Vercel's own Bedrock access, not yours. To use a different model, change AI_GATEWAY_MODEL to any model ID the Gateway supports — that's the only thing you need to change, in code or in your Vercel project's environment variables. All model selection is centralised in src/lib/ai.ts.
Environment variables — copy ENV_TEMPLATE.md into .env.local and fill in every value from steps 1-4. Nothing in this repo has default values for these; the app won't start without them.
Run it:
npm install
npm run dev
Or deploy to Vercel and set the same variables in the project's Environment Variables settings.
src/app/ — routes: citizen chat (chat), case view (case), delegation controls (api/delegation), the MCP server (api/mcp), the synchronous first-login provisioning endpoint (api/provisioning/sync), and an access log (access-log)fga-model.fga — the Auth0 FGA authorisation modelauth0-actions/ — Auth0 Action source (deployable via the auth0 CLI — see setup step 1 — or pasted into the dashboard)firestore.rules — Firestore security rules for cases, agents, auditEventssrc/lib/provisioning.ts, src/lib/firebase-admin.ts — Firestore data accesssrc/lib/roles.ts — reads the citizen/caseworker persona claim the Actions set on the ID token; this is the app's only RBAC mechanismauth0 actions deploy <id>