API

Authentication

CDA uses Supabase Auth with OAuth providers for all API authentication. There are no username/password credentials. This is the Empty Fortress model.

Supported OAuth providers: Google, GitHub, Microsoft, LinkedIn.

Obtaining a JWT:

1. Initiate an OAuth flow via the Supabase Auth client: const { data, error } = await supabase.auth.signInWithOAuth({ provider: "github", options: { redirectTo: "https://your-app.com/callback" } });

2. After the redirect, exchange the code for a session: const { data: { session } } = await supabase.auth.getSession(); const jwt = session.access_token;

3. Use the JWT in all API requests: Authorization: Bearer <your_jwt_token>

Token structure:

The JWT contains: - sub: The user's Nexus ID (nexus_profiles.id, equals auth.uid()) - email: The user's email address - role: "authenticated" - app_metadata: Provider info, tier, and connected providers - exp: Expiration timestamp (default: 1 hour)

Token refresh:

Access tokens expire after 1 hour. Use the refresh token to obtain a new access token: const { data, error } = await supabase.auth.refreshSession();

The Supabase client handles refresh automatically when configured. If you are making raw HTTP requests, call: POST https://nprzmfiqtqvoljvcvsyi.supabase.co/auth/v1/token?grant_type=refresh_token Body: { "refresh_token": "your_refresh_token" }

Row-Level Security:

All CDA tables use Supabase RLS. The JWT is evaluated server-side to determine which rows the caller can access. You do not need to pass org_id or user_id manually. RLS policies enforce: - Users see only their own nexus_profiles data - Org members see only their organization's data - Public tables (wiki_articles with status=published, theater_missions, theater_domains) are readable by all authenticated users - Write operations require appropriate roles (admin, owner, or specific cda_role values)

API key header:

In addition to the Authorization header, include the Supabase anon key: apikey: <your_supabase_anon_key>

This is a public key and safe to include in client-side code. It identifies the project but does not grant elevated access.

Common errors: - 401 Unauthorized: Token is missing, expired, or malformed - 403 Forbidden: RLS policy denied access (insufficient role or tier) - 400 Bad Request: Missing apikey header