Skip to content
cccskills
FreePublished on GitHub

authentication-portal-api

Build or troubleshoot HTTP clients for an authentication portal’s JSON login, token refresh, Documents, profile, and admin APIs. The skill explains request and response contracts, browser and native transports, and public signing-key discovery so clients can interact with the configured portal correctly.

OriginalShow the original description

Build or troubleshoot portal JSON/native login clients, refresh, Documents, profile and admin APIs, and public JWKS. Use for HTTP contracts; portal Caddyfile wiring belongs to configuration-authentication.

Run score Not tested

See how to install

Good for

  • Implement a JSON login client for a portal
  • Troubleshoot browser or native token refresh
  • Call profile, Documents, or admin endpoints
  • Discover public signing keys through JWKS

Files included (10)

  • SKILL.md14.9 KB
  • agents/openai.yaml253 B
  • references/admin-api.md7.3 KB
  • references/authentication-flows.md5.2 KB
  • references/browser-refresh.md11.9 KB
  • references/connected-accounts.md6.1 KB
  • references/documents.md8.1 KB
  • references/native-client.md15.0 KB
  • references/openapi-contracts.md5.1 KB
  • references/profile-public-keys.md4.7 KB

SKILL.md (original)

Review the instructions the agent will receive before you install.

Authentication Portal API

Purpose

Use this skill for HTTP/JSON interactions with a configured authentication portal. Surrounding Caddyfile declarations belong to configuration-authentication; route mounting belongs to configuration-http-integrations. These are configuration boundaries, not prerequisites for an HTTP client task.

For user-owned profile keys, legacy PGP/RSA metadata, ownership isolation, and canonical profile identity and transformed-claim isolation, read profile public keys. For conditional login selection, authoritative AMR and profile policy preview/ replacement, read authentication flows. For password/MFA mutations and refresh/OIDC invalidation, read local identity compatibility. For authored schemas, mounted endpoint contracts and wire-format exceptions, read OpenAPI contracts. For encrypted file operations, current local browser-session authority, sharing and client key recovery, read Documents API. For explicit external-account connection, fresh browser proofs and one-use confirmation, read connected accounts.

For the standalone caddy-authenticator CLI, profile configuration, terminal input and private storage, use the command maintenance reference. Keep fresh login delegated to the public authclient package; the command owns cached-token scheduling and its explicit native refresh request.

Read these files when details matter:

  • ../go-authcrunch/pkg/authn/handle_json_*.go for JSON handlers and response shapes.
  • ../go-authcrunch/pkg/authn/handle_http_*.go for browser versus JSON behavior.
  • caddyfile_authn.go and caddyfile_authn_admin_api.go for admin directives.
  • ../go-authcrunch/pkg/authn/admin_api/parser/parser.go, admin_api_config.go, respond_api.go, and handle_api_private_keys.go for the admin configuration and authorization boundary (the latter three files are directly under pkg/authn).

Upstream handler paths are read-only references under the repository scope. Keep client changes and integration tests here. If an API fix belongs to go-authcrunch, describe the separate upstream work instead of editing or testing that checkout.

JSON Requests

Portal JSON dispatch accepts the exact header value or query signal below:

Accept: application/json
format=json

Accept lists, quality parameters and application/json; charset=utf-8 do not select this JSON dispatch. Without a recognized signal, many endpoints render HTML or redirect. Dedicated API, provider and discovery routes keep their own dispatch rules; do not normalize upstream negotiation in the Caddy handler.

Assume endpoint paths are relative to the portal base path. If the portal is served at /auth, then /login means /auth/login, /whoami means /auth/whoami, and admin endpoints are under /auth/api/server/....

Login Challenge Sequence

For the public Go client, native transport, API-key login and private credential files, use JSON/native interoperability. Authenticate performs fresh login; renewal is a separate explicit operation.

Programmatic login is challenge-based:

  1. POST <base>/login with username and realm.
  2. The portal returns sandbox_id, sandbox_secret, and next_challenge.
  3. The client posts the same identity plus sandbox_id, current sandbox_secret, challenge_kind, and challenge_response.
  4. The portal may rotate sandbox_secret and return another challenge.
  5. When all checkpoints pass, access-only JSON login returns authenticated: true, access_token_name, and access_token. An enabled, participating local refresh login instead uses the transport contract below: browser tokens arrive in cookies; opted-in native clients receive JSON tokens.

Common challenge kinds are password, totp, and mfa. The public Go authclient supports password/TOTP, including combined MFA selection. It does not implement WebAuthn/U2F assertions and returns ErrUnsupportedChallenge for an assertion challenge. A separate client that supports assertions first answers challenge_kind: mfa with challenge_response: webauthn; the next challenge contains a base64-encoded WebAuthn payload. The final response must contain the signed WebAuthn result.

Do not reuse an old sandbox_secret; use the latest value returned by the portal. Sandbox sessions are temporary and separate from the final JWT session.

Portal Refresh Transports

Use the token refresh configuration for explicit participating local/provider realms, origin, mount, cookie naming and limits. The selected go-authcrunch implements real rotation; /api/refresh_token is no longer a timestamp probe. No enabled block means access-only behavior and 404 at the refresh/session API routes.

Browser login uses the default cookie transport. Tokens arrive in HttpOnly cookies and JSON contains session/expiry metadata without bearer credentials. After login, POST {} as JSON to <base>/api/refresh_token, <base>/api/logout, or <base>/api/refresh_session with the cookie jar, exact configured HTTPS Origin, and X-Authcrunch-Refresh: 1. Disallowed fetch metadata, origins or mixed transports fail closed. Responses preserve Cache-Control: no-store. A valid refresh cookie can rotate despite an expired or malformed access token. The browser coordinator also sends the optional rotation precondition X-Authcrunch-Refresh-Session; forward it unchanged. Session lookup is browser-only and must never recover an uncertain rotation. See browser refresh through Caddy for continuation, coordination, strict request parsing, fresh-login recovery and real Chrome tests.

Native clients require body transport enabled and send refresh_transport: body at every login checkpoint. Send no Cookie, Origin or Sec-Fetch headers. Login and rotation return access_token, refresh_token, names, session ID, and expiry metadata in JSON without cookies. Subsequent POSTs use {"refresh_token":"<credential>"}. Omitting explicit native opt-in selects browser transport; enabling the feature alone does not opt clients in.

Successful rotation changes the refresh credential and access-token jti, retains the session binding and absolute deadline, and reloads current local identity attributes. Replaying an old refresh token revokes the family. Serialize rotations and avoid automatic retries when delivery is ambiguous. Invalid/revoked credentials return 401, origin/transport violations 403, admission exhaustion 503. A family's rotation-limit exhaustion revokes it and reclaims capacity.

Selecting managed refresh storage changes durability and limits, not the wire transport or proof requirements. Refresh API failures from unavailable storage or commit uncertainty return 503. Issuance that reports an uncertain commit also returns 503 and withholds staged access, refresh and downstream OP credentials. A failed response does not establish that the credential remained unused; even explicit 503 must not trigger automatic retry, session lookup recovery or silent fallback to fresh credentials. The browser coordinator blocks the affected family until confirmed fresh login; persistent native consumers must retain uncertainty across process restarts and require an explicit recovery action. A 401 denial is a different status, but also does not authorize retry of the same failed rotation.

With a refresh cookie, GET <base>/logout displays confirmation; the session API POST completes revocation and cookie deletion, including an associated OP session. Portal refresh grants are unrelated to OIDC refresh or upstream provider refresh. API-key and other unsupported login kinds remain access-only. TestCaddyTokenRefreshE2E covers these transports through verified Caddy TLS.

Explicitly selected OAuth/OIDC snapshot callbacks also issue cookie-transport families. They preserve captured upstream identity while rechecking current local attachment and portal policy; they do not contact upstream token/userinfo during renewal. The signed local account id, upstream subject, and family SID have distinct meanings. Local account/security mutations can invalidate the original proof, requiring fresh login. Native body opt-in does not change callback transport or grant local profile/OP authority. See provider renewal for selection, credential sanitization and restart requirements.

Status And Identity Endpoints

Use /beacon for a light authentication probe with JSON negotiation. A valid portal-admitted token returns status 200 and the two raw bytes OK, despite Content-Type: application/json; do not JSON-decode success. Missing or invalid credentials return a JSON error with status 401. Without JSON negotiation the route returns an HTML 404. Responses use Cache-Control: no-store.

Use /whoami for the current user claims. Useful query parameters include:

  • probe=true: include authenticated and expires_in.
  • format=json: force JSON when no JSON Accept header is present.
  • id_token=true: include the upstream identity provider ID token when an OAuth provider was configured with enable id token cookie.

JSON time claims are Unix seconds; expires_in is a remaining duration in seconds. HTML identity views can format times for display. Do not copy those display strings into JSON clients. The distinct probe=login browser check also requires a stored portal session; a valid token alone does not establish it.

Send access tokens using the portal-supported Authorization header or cookies that match the portal's token validator configuration. If custom access-token cookie names are used, keep portal and authorization policy names aligned with configuration-authentication-cookies and configuration-crypto.

Public Signing-Key Discovery

GET <mount>/.well-known/jwks.json returns the public keys used for portal access-token signing. HEAD returns the same headers and Content-Length with no body. No enable directive, session, admin API, or private-export setting is required. Requests with invalid credentials, JSON headers, or format=json still reach discovery before authentication and content negotiation.

For ordinary KMS issuance, the first eligible non-system signer determines availability: an asymmetric signer enables discovery, while HMAC first returns 404 even when asymmetric signers follow. Ordinary verification-only keys never enable discovery. When available, the endpoint publishes RSA, EC, and Ed25519 signing public keys in signing order, excluding HMAC, verification-only, and System API keys. Success is an object with a keys array, including for one key, using application/jwk-set+json. All methods use Cache-Control: no-store and nosniff, without cookies or login redirects. Unsupported methods return 405 with Allow: GET, HEAD.

An explicitly selected PS256 access signer instead publishes its current public key plus the configured profile's retained verification keys, sorted by key ID. Each advertises PS256 and contains public RSA material only. The shared HTTP and mount rules remain the same. See selected access signing for profile trust, rotation and private-key export isolation.

Ed25519 keys use kty: OKP, crv: Ed25519, and a 32-byte unpadded base64url x; no private d or EC y appears. Match the exact alg and kid to the signed JWT. Generated keys can advertise EdDSA or Ed25519; imported keys default to EdDSA. Default key ID 0 is omitted in both JWT and JWK. See crypto settings for key sources and labels.

An explicit authenticate with <portal> at <mount> declaration enforces the literal mount boundary before discovery, including under a broad Caddy matcher. Discovery then requires the exact mounted /.well-known/jwks.json path in both decoded and escaped form. Omitted mounts retain legacy inference and suffix routing; qualify that mode separately. Trailing slashes, filename suffixes and query-only matches are not discovery. See public JWKS routing to keep it ahead of a protected catch-all. This endpoint is distinct from /oidc/jwks and the OP's dedicated RS256 ID-token signing keys.

TestCaddyJWKSE2E verifies the HTTP contract over trusted TLS, reconstructs public keys from discovery to verify real login tokens independently, and checks gatekeeper rejection of wrong keys and tampered tokens. Its first request is HEAD, and negative-route checks inspect both headers and bodies. TestCaddyJWKSPersistenceE2E checks ordinary KMS rollover across fresh processes: retained verification keys continue accepting old tokens without publishing them; removing those keys on reload rejects cached old tokens. Discovery publishes current signing configuration and does not retain removed keys automatically.

Admin Server API

Admin endpoints require the configured admin API and a valid portal-admitted access token with an admin role. They do not require the stored profile session. Private signing-key export is independently disabled by default and requires both flags plus administrator authorization. Public JWKS is separate and needs neither flag. Read admin/server API contracts for endpoint shapes, exact status/method behavior, key formats, and Caddy tests.

Troubleshooting

  • Missing JSON response: add Accept: application/json or format=json.
  • Login sequence fails after password: verify the client preserved the latest sandbox_id, latest sandbox_secret, and expected challenge_kind.
  • MFA prompts unexpectedly: inspect user tokens, require mfa transforms, and auth challenge rules stored in the local user database.
  • /whoami omits upstream ID token: verify the OAuth provider uses enable id token cookie ... and the browser/client sends the ID-token cookie.
  • /api/refresh_token failures: check explicit realm participation, configured origin/mount, the required browser header, native opt-in, and replay/capacity limits using the transport contract above.
  • Admin endpoint returns unauthorized: verify enable admin api, a valid portal-admitted access token, and authp/admin or equivalent portal admin role.

Reviews

No reviews yet. Tell others what you thought.

Comments

No login needed. Share how it worked for you, ask a question, or note where it did not run.

No comments yet. Be the first to write one.

Comments are published right away. Do not include personal information such as email addresses or phone numbers. Up to 2 URLs.

0 / 1,000 characters

This form is protected by reCAPTCHA, and the Google Privacy Policy and Terms of Service apply.

More skills from this repository

Investigate caddy-security deployment and runtime failures using configuration, logs, version details, and HTTP evidence. The skill helps identify a focused correction or document an unresolved issue with a useful handoff, while keeping observed facts separate from hypotheses and redacting secrets.

  • Diagnosing login, callback, or authorization failures
  • Finding a minimal correction for a Caddy configuration
  • Preparing a redacted break-fix issue report
greenpau/caddy-security2.3KUpdated Oct 26, 2026

Use these conventions to implement or review caddy-security Go code, Caddy modules, Caddyfile parsers, and HTTP integrations. Keep app boundaries and lifecycle behavior clear, delegate authentication logic to go-authcrunch, and handle errors and logs safely.

  • Reviewing a Caddyfile parser change
  • Adding a Caddy module or HTTP handler
  • Checking app lifecycle and cleanup behavior
greenpau/caddy-security2.3KUpdated Oct 26, 2026

configuration

FreeSummary

Build or review caddy-security Caddyfiles by starting with the security app and wiring authenticate or authorize routes to named portals and policies. Use its domain map to find focused guidance for the requested login, provider, storage, or integration setup.

  • Drafting a complete caddy-security Caddyfile
  • Wiring portal authentication into routes
  • Connecting authorization policies to protected paths
greenpau/caddy-security2.3KUpdated Oct 26, 2026

Configure Caddy authentication portals and connect them to protected routes. Select login backends, set trusted login and logout redirect rules, and wire portal behavior such as refresh and Documents storage while relying on focused skills for specialized settings.

  • Create a portal and connect it to protected routes
  • Choose which identity stores and providers can log in
  • Set trusted login and logout redirect destinations
greenpau/caddy-security2.3KUpdated Oct 26, 2026

Set authentication portal cookie names, prefixes, domains, paths, and browser attributes, including refresh-cookie overrides. The guidance explains naming precedence, validation, and how authorization policies must explicitly discover matching token cookies.

  • Giving portal cookies a shared prefix
  • Overriding one cookie name
  • Setting cookie paths and domains
greenpau/caddy-security2.3KUpdated Oct 26, 2026

Configure optional cross-device portal login, where one device starts a request and another scans a QR code and explicitly approves it after fresh authentication. Review browser binding, cancellation, expiry, credential delivery, and lifecycle behavior through Caddy.

  • Add QR-based login approval from a second device
  • Require explicit approval after fresh authentication
  • Review cancellation and expired request behavior
greenpau/caddy-security2.3KUpdated Oct 26, 2026

See all skills by greenpau

Report a problem with this skill