my-auth-api
$
npx mdskill add myapihq/myapi/my-auth-apiAdd OIDC authentication to apps you build on MyAPI.
- Manage end-user authentication for apps deployed on MyAPI.
- Uses MyAPI's managed OIDC identity provider with RS256 tokens.
- Verifies tokens locally against the tenant's JWKS endpoint.
- Delivers OIDC client registration and hosted login pages.
SKILL.md
.github/skills/my-auth-apiView on GitHub ↗
--- name: my-auth-api version: 1.0.0 description: > Add authentication to apps you build on MyAPI — a managed OIDC identity provider for your app's END USERS (à la Kinde/Auth0). One auth tenant per org; register OIDC clients; sign users in with managed Google or the hosted login page; verify RS256 tokens against the tenant JWKS. triggers: [auth, authentication, login, sign-in, oidc, oauth, jwt, jwks, sso, google sign-in, user accounts, identity provider, kinde, auth0, clerk] checksum: sha256-pending --- # MyAuthAPI Authentication for the **end users of apps you build on MyAPI** — not your MyAPI account (that's `myapi account`). It's a managed multi-tenant **OIDC identity provider**: each org gets one auth tenant, you register OIDC clients (your apps) against it, and your users sign in via managed Google or the hosted login page. Tokens are RS256, verified locally against the tenant's JWKS — no per-request call back to MyAPI. ## Capabilities <!-- llm:start --> Auth is the identity layer for apps an agent deploys (containers, funnels). It closes the gap between "shipped an app" and "the app has real users with accounts" — natively, on the same org/domain/bill, no third-party auth to wire. **Mental model:** one **tenant** per org (your identity provider) → many **clients** (your apps) registered against it → end users sign in and get RS256 tokens your app verifies against the tenant **JWKS**. The standard OIDC machine endpoints live under the tenant issuer and are consumed by your app + the JS SDK, **not** the CLI: `/.well-known/openid-configuration`, `/jwks`, `/authorize`, `/token`, `/userinfo`. The CLI manages the two things you set up by hand: the tenant and its clients. - **Tenant** — `auth tenant create` provisions (idempotent) your org's OIDC issuer + hosted login URL. `auth tenant` shows them. - **Client** — `auth client create` registers an app. `type spa` is a public client (no secret; for browser/SPA/mobile). `type web` is confidential and returns a `client_secret` **once** — store it immediately. `--redirect` lists allowed callback URIs (absolute https, or http://localhost for dev). - **Usage** — `auth usage` shows monthly active users (auth is billed per MAU). - **Custom domain** — serve auth on `auth.acme.com`. Three steps: `auth domain set --domain auth.acme.com` prints a **TXT ownership challenge**; publish it, then `auth domain verify`; that prints the **A record** to publish, TLS provisions automatically, and the domain becomes your issuer once active. **Sign-in methods** are chosen per tenant via `auth tenant create --connections google,password,magic` (default `google`): **managed Google** (no customer GCP account), **email/password** (with verification + password reset), and **magic links** (passwordless email). All are served by the hosted login page. Verifying tokens, the authorize/token dance, userinfo, and the password/magic/reset flows are handled by the hosted page + standard OIDC — point any OIDC client library at the tenant issuer; the CLI is only the management surface. <!-- llm:end --> ## Commands <!-- generated:start --> | Command | What it does | |---|---| | `myapi auth tenant` | Show your org's OIDC auth tenant (issuer + hosted login URL + sign-in methods) | | `myapi auth tenant create` | Create/enable the tenant (`--connections google,password,magic`; `--theme <json>`) | | `myapi auth client list` | List the OIDC clients (apps) registered to your tenant | | `myapi auth client create` | Register an OIDC client (`--name`, `--type spa\|web`, `--redirect`) | | `myapi auth client delete <id>` | Revoke a client (irreversible); `--yes` to skip the confirm | | `myapi auth client rotate <id>` | Re-issue a `web` client's secret (shown once) | | `myapi auth usage` | Monthly active users (MAU) for the current period (`as_of` shows freshness) | | `myapi auth domain` | Custom auth domain: `set` (TXT challenge) → `verify` → A record; also `show`/`delete` | <!-- generated:end --> ## Examples <!-- llm:start --> ```bash # 1. Provision your org's auth tenant (one time) myapi auth tenant create # → issuer + login_url for the hosted login page # 2. Register your app as an OIDC client # SPA / browser app (public, no secret): myapi auth client create --name "My SPA" --type spa \ --redirect https://app.example.com/callback # Server-side / confidential app (secret returned ONCE): myapi auth client create --name "My API" --type web \ --redirect https://app.example.com/auth/callback # 3. Inspect myapi auth tenant myapi auth client list # 4. In your app: point any OIDC client library at the tenant `issuer`. # Verify access tokens locally against <issuer>/jwks (RS256) — no call back. ``` <!-- llm:end --> ## Tenant vs client - **Tenant** = your identity provider (one per org). It owns the issuer, signing keys (JWKS), and the hosted login page. Create it once. - **Client** = one app authenticating against the tenant. Register one per app (or per environment). `spa` = public, `web` = confidential (has a secret). ## Operator auth is different `myapi auth` is for **your app's users**. To manage **your own MyAPI account** (login, API keys, billing config), use `myapi account` (`whoami`, `link`, `api-keys`, `config`, …). ## Notes - The `client_secret` for `web` clients is shown **once** at creation and cannot be retrieved later — store it immediately. SPA clients have no secret. - Redirect URIs are matched exactly: absolute `https://…` (or `http://localhost…` for local dev). - `402 INSUFFICIENT_FUNDS` = empty wallet → `myapi billing topup <amount>` (or keep it funded automatically: `myapi billing auto-recharge set`). `402 SPEND_CAP_EXCEEDED` = you hit your account spend ceiling → raise it with `myapi billing spend-cap`.