本文へ移動
cccskills
無料GitHub で公開

oauth-identity-provider

Maintain upstream OAuth identity-provider directive parsers, shared configuration dispatch, OAuth/OIDC discovery, GitHub identity claims, JWKS and static public PEM verification, EdDSA/Ed25519 token validation, key refresh, and real portal OAuth E2E tests. Excludes portal signing-key publication and gatekeeper-owned direct OAuth sessions.

インストール方法を見る

含まれるファイル(3)

  • SKILL.md22.3 KB
  • agents/openai.yaml342 B
  • references/configuration-directives.md10.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

OAuth Identity Provider

authorization-policy-oauth owns policy-selected login without a portal, its parser, callbacks, and opaque sessions. That peer consumer reuses this provider's authentication protocol and trust checks.

Use refresh-token-implementation to maintain opt-in portal renewal after verified upstream login. That consumer's snapshot mode captures claims before transformations and never renews upstream tokens. Keep callback state/nonce/PKCE and signature verification in this owner; selected snapshot providers must disable upstream identity-token cookies.

Ownership and Entry Points

pkg/idp/config.go validates the shared provider parameter allowlist; pkg/idp/provider.go constructs the concrete provider. OAuth behavior lives under pkg/idp/oauth. Exercise this dispatcher as well as concrete helpers: an OAuth Config field is not usable through the shared API until dispatch accepts it and checks its type.

pkg/idp/oauth/parser.NewOAuthIdentityProviderConfigFromDirectives returns *oauth.Config. pkg/idp/parser.NewOAuthIdentityProviderConfigFromDirectives reuses that parser and returns *idp.IdentityProviderConfig for the shared dispatcher or root Config.AddIdentityProvider. Both take the provider name and encoded body statements. Keep grammar in the OAuth parser; the shared adapter owns only normalized configuration conversion and allowlist validation. See directive parsing for the complete grammar, application examples, parser maintenance, defaults, and validation boundaries.

authenticate.go owns redirects and code exchange; validator.go owns token roles and trust claims; jwt.go owns signature verification and bounded retry; jwks.go owns key conversion; jwks_store.go owns remote ingestion, static pins, candidate selection, and refresh. provider.go owns setup/discovery.

The provider verifies upstream credentials. The portal subsequently signs a separate credential using its existing KMS configuration. Keep upstream keys, algorithms, issuer metadata, and key refresh independent of portal signing selection, token settings, and portal JWKS publication. ES512 is the existing autogeneration fallback, not a mandatory portal signing algorithm.

GitHub identity claims

The GitHub driver derives github_id only from the numeric id in its successful authenticated /user response. Decode that value losslessly from the original JSON as a positive unsigned 64-bit integer and emit a canonical decimal string; a float64 conversion can authorize the wrong large ID. Preserve metadata.id as a JSON number and the existing sub = github.com/<login>. An absent ID remains compatible with older profile fixtures but emits no github_id. Reject a supplied null, string, zero, negative, fraction, exponent or overflow. Never accept an upstream field already named github_id as proof.

When user_org_filters enables the existing GitHub organization lookup, project accepted organization login values into the string list github_orgs as well as the existing github.com/<org>/members groups. For example, provider body directive user_org_filters .* admits all returned organizations; narrower regex filters restrict both outputs. Derive the list from fetched organization records, never the profile's arbitrary extra fields or transformed roles. Missing/disabled lookup, an empty or filtered result, an HTTP/API failure, or invalid organization login types cannot grant an organization match. Existing lookup failures remain nonfatal for login and produce no organization claim.

The lookup follows the profile's validated GitHub API organizations_url and retains its existing response/visibility behavior, including its current single page. GitHub's list-user-organizations endpoint returns public memberships; adding read:org alone does not change that endpoint to the authenticated-user API or expose private memberships. This feature adds matching over those results, not private-membership discovery or pagination.

The transform parser and portal provider boundary are owned by GitHub identity matchers. Other drivers must not forward either reserved top-level claim. The public factory assumes its embedding caller has authenticated the claim source; a realm called github is not proof of the configured driver.

Validate changes with TestGithubIDFromProfile, TestGithubOrganizationClaims, transform parser tests/examples, and the default-suite TLS consumer TestE2EOAuthGithubTransforms. Its isolated subprocess confines proxy routing for fixed GitHub hosts to local listeners and preserves production endpoints. It covers large adjacent IDs, unchanged subjects/metadata, renamed accounts, malformed IDs, exact/regex membership, org filters and lookup failures, non-GitHub claim spoofing, and combined matchers through a protected resource.

make test TEST_DIR='./pkg/authn ./pkg/authn/transformer/... ./pkg/idp/oauth/... ./pkg/acl' COVERAGE_DIR='.coverage/github-transforms'
make test-automation

Ed25519 Verification Contract

internal/jwtutil registers the exact Ed25519 JOSE name and recognizes the two concrete supported methods. The pinned JWT library provides EdDSA. Both use pure Ed25519 over the original JWS bytes. Preserve exact method names and never rewrite a signed header, prehash the message, or duplicate registry initialization. KMS also consumes this helper. The key representation follows RFC 8037; the fully specified JOSE name follows RFC 9864.

New OKP keys require crv: Ed25519 and canonical unpadded base64url x with exactly 32 bytes. Return a typed ed25519.PublicKey, never an HMAC byte secret. Reject encryption use, incompatible public parameters, private d, and other curves. Ed448 and X25519 are unsupported. Unknown unrelated extensions can be ignored. For key_ops, omission allows verification; an explicit list must contain verify, may also contain sign, and cannot contain duplicates or other operations. Empty, null, and malformed lists are rejected for OKP. Present empty or null alg/use values are invalid in remote OKP entries; Go struct zero values still represent omitted optional fields.

Ed25519 key restrictionAccepted JWT alg
JWK alg omittedEdDSA and Ed25519
JWK alg EdDSAEdDSA
JWK alg Ed25519Ed25519
Public PEMEdDSA and Ed25519

JWT header values are case-sensitive. Keep the explicit RS/ES/PS/Ed allowlist, concrete method checks, and typed verification candidates. HS and none receive no verification keys. Preserve existing RSA-PSS verification with an algorithm-unspecified RSA JWK. Explicit PS-labelled RSA JWKs remain outside the legacy JWK parser's accepted metadata. Do not silently tighten legacy RSA/EC alg/use/key_ops policy as part of Ed maintenance. Remote decoding deliberately ignores legacy key_ops, including values the old decoder did not inspect; apply its new typed validation only to OKP.

Configuration and Static Keys

Discovery uses the existing metadata_url and its jwks_uri. Advertised id_token_signing_alg_values_supported values neither change the portal signer nor become an access-token algorithm policy. Unknown advertised capabilities do not prevent using supported keys.

jwks_keys / Config.JwksKeys maps explicit key IDs to public PEM paths. NewJwksKeyFromPublicKeyPEM accepts Ed25519 PKIX/SPKI PUBLIC KEY, RSA PKIX PUBLIC KEY, and RSA PKCS#1 RSA PUBLIC KEY. The RSA-specific exported constructor retains its RSA-only contract. Private PEM, SSH, and certificate formats are not added by this feature.

Configuration validation reads static keys; provisioning must also install them into runtime verification state. Fully explicit authorization/token URLs and static keys work without metadata or a disable flag. In combined mode, fetch configured discovery while preserving explicit endpoint overrides. Static IDs take precedence over remote entries and survive remote replacement.

key_verification_disabled retains its existing fetch-control meaning: static JWT signatures are still verified. Do not prescribe disabled nonce, PKCE, or TLS verification as a production prerequisite for Ed support.

The shared AuthCrunch configuration accepts the OAuth issuer and access_token_audience string fields. An explicit issuer overrides discovered issuer information. Do not derive issuer from base_auth_url. Static-only users can supply issuer explicitly; absent issuer keeps the existing optional issuer-check contract. The public parsers accept both settings as single-value directives. Embedding-server block recognition and parser wiring are separate consumer work; never edit sibling checkouts to implement or validate them.

Selection and Refresh

Remote JWK kid may be omitted. Explicit public constructors still require the caller-supplied ID. A present JWT kid must be a nonempty string and restricts candidate lookup to that ID; an unknown kid never falls back to other IDs. Without kid, select compatible trusted candidates. Retain same-kid alternatives and use the JWT library's VerificationKeySet for actual signature verification. Apply each OKP entry's restrictions before deduplicating public material.

Snapshots are immutable after publication. keyMu protects snapshot/version publication; keyFetchMu serializes refresh and its rate accounting. Network work happens outside keyMu. A fetch version includes failures so concurrent waiters reuse the outcome. Never mutate published maps or keys in place.

Limits are 1 MiB per metadata/JWKS response and 64 entries per remote or static key set. Oversized documents fail rather than being truncated. Individual invalid/unsupported remote entries do not poison valid siblings. A complete empty or all-invalid keys array replaces the remote set with no usable entries and returns an error; malformed documents and transport/HTTP failures preserve the previous snapshot. Static pins are retained in either case.

Refresh allows four attempts, then a five-minute cooldown from the latest attempt. Unknown keys and actual signature failures can cause at most one refresh/retry per token validation. Signature failure supports same-kid material replacement. Claims failures, unsupported methods, and failures for an explicit static ID do not trigger refresh. Propagate request context to request-driven JWKS fetching.

Removed remote keys stop verifying after a successful refresh observes their removal. There is no periodic refresh or instantaneous revocation promise. Upstream key removal does not revoke already-issued portal sessions.

Delayed setup publishes metadata before admitting authentication; setupMu protects discovery changes and config reads. IdentityProvider.Close cancels and awaits owned synchronous/delayed discovery, metadata/JWKS HTTP work, retry timers, and the OAuth state worker. Registration of setup work and shutdown are serialized; no worker may be added after shutdown begins or publish readiness after Close returns. Configure calls serialize and reuse successful setup; closed providers cannot be configured or authenticate again. Embedders drain requests before disposal. The root Server.Close owns shared providers once; individual portals do not own their lifetime. Direct provider consumers call Close themselves.

Browser State and Nonce Policy

state.go atomically publishes nonce, PKCE verifier and login binding. Bind a five-minute, single-use callback to the initiating protected browser SessionID and exact callback URL. Claim it atomically before processing any code or direct token; delete it on every completion/error path. State is distinct from the browser cookie, and a supplied state must never create its own browser binding.

IdentityProvider.CancelLogin(state, sessionIDHash, callback) atomically removes state only for the exact callback and SHA-256 of its initiating SessionID. It is idempotent and supports pending or claimed transactions. Keep this optional provider capability separate from the shared idp.IdentityProvider interface; direct authorization consumers require it to release canceled transactions. Consumers must still prevent session issuance after their own logout or closure; removing state does not promise to interrupt an already-running HTTP exchange.

Capture nonce policy when login starts. NonceDisabled omits nonce from the authorization URL (including a preconfigured nonce parameter) and skips only the nonce-claim check for that transaction. An enabled transaction requires its exact stored nonce. Later config changes cannot weaken an existing transaction; legacy state entries fail closed to nonce-required behavior. Missing state still fails. Signature, issuer, audience, browser state, expiry, replay and PKCE validation remain active when nonce compatibility is disabled.

The login binding also carries the embedding application's post-login destination: the requests.Response.ReturnURL present when login starts is published with the binding and is opaque to the provider. It never enters the authorization URL. Successful completion also sets runtime ReturnURLBound, including an empty destination, so the portal cannot fall back to another tab's cookie. The portal revalidates the destination at grant and uses the shared 16384-byte bound. Every callback request clears any ReturnURL it carried before the state is claimed, and sets the bound value only on success, so neither a callback URL nor a failed or unadmitted callback can choose a destination. The value is read before the claim; it never changes once published. The destination shares the binding's capacity, lifetime, single use and removal on completion, cancellation and expiry. The embedding portal validates it before login and again before use. RedirectURL stays reserved for the authorization endpoint.

Keep nonce_policy_test.go, state_binding_test.go, parser round-trip OAuth TLS coverage and oauth_state_e2e_test.go for both settings, wrong/missing nonce, wrong browser/callback, replay and malformed signed identity tokens. TestStateBindingReturnURL and TestE2EOAuthTokenCallbackReturnsBoundDestination cover the bound destination's lifecycle, interleaved callbacks, callback-carried destinations, failed callbacks and unknown states.

Claims and Protocol Compatibility

An invalid ID token or selected identity access token fails authentication. An unusable optional JWT access token contributes no claims. Opaque access tokens retain their existing bearer/UserInfo behavior. Preserve the existing issuer, audience, azp, time, state, nonce, and PKCE checks and role processing. Do not turn optional legacy claims into new requirements without an explicit compatibility decision. Malformed nonce/name values must return errors, not panic. Several named drivers intentionally use UserInfo-oriented fetchClaims instead of the common JWT path; preserve that dispatch. Named-driver fetchClaims requires a nonempty string access token, a successful UserInfo HTTP status, and at most 1 MiB of response JSON. Reject oversized bodies instead of truncating into an accepted identity, and do not panic on malformed token response types. Synthetic TLS tests cover these boundaries without calling the named provider's live service. Authorization-code exchange responses, including the Facebook variant, are also limited to 1 MiB before JSON decoding. Reject an oversized document even when its prefix is valid JSON. Treat error and error_description as optional strings; malformed values fail without a panic and without copying aggregate provider data into the returned error. Keep the real portal callback regression proving an oversized token response issues no portal credential. Generic OIDC UserInfo enrichment also requires a nonempty string access token, a 2xx response, and no more than 1 MiB of JSON before decoding. A failed or oversized optional enrichment must not replace roles from the already verified identity; login may continue with those verified claims. Keep the real TLS portal regression proving an oversized UserInfo document cannot add a role and the original verified role still authorizes. Test the exact size boundary and reject provider-controlled access-token types without a panic. Discord guild-list and guild-member enrichment requires 2xx responses and the same 1 MiB bound for every request. Decode guild IDs, names, permissions, and member role IDs into typed fields; reject malformed types, missing/empty IDs, and the complete enrichment result rather than panicking or issuing partial groups. Keep the isolated TLS/CONNECT E2E because these production endpoints are fixed Discord hosts. It must cover valid admin groups, malformed provider types, oversized documents, and non-success responses for both follow-up routes. Google Cloud Identity group enrichment requires nonempty string access-token and email inputs, a 2xx response, and the same 1 MiB limit. Validate every group display name and all existing role elements before atomically publishing the merged role list; a failure must leave prior roles unchanged. Keep its fixed-host TLS/CONNECT E2E for malformed signed-claim types, non-success and oversized responses, and its decoder/merge unit matrix. GitHub's provider-supplied organizations_url is valid only on the HTTPS api.github.com origin with the default TLS port, no userinfo or fragment, and a nonempty path. Organization and fixed email follow-ups do not follow redirects; both require 2xx responses and the same 1 MiB bound before JSON decoding. Keep the isolated TLS/CONNECT E2E for arbitrary origins, redirect attempts, non-success/oversized responses, and valid organization/email enrichment. Cognito extension handling consumes the already signature/trust-verified claims map; do not decode the raw JWT payload a second time. Validate custom roles, groups, timezone, username, and zoneinfo types before publishing any derived claims. Malformed signed values return an authentication error without partial mutation or panic; custom:timezone deterministically overrides zoneinfo. Keep both the atomic parser unit matrix and signed-RSA validation E2E. Keep required/error JSON field validation in validateFetchedClaims before mapping. Incorrect GitHub login/organization fields, Discord IDs and Facebook identity/error types must not panic. Tests must distinguish parser rejection from transport failure: include valid controls and observe the expected TLS request and error, not just a nonnil error.

provider_direct_authorization_e2e_test.go covers provider cancellation capacity and a synthetic LinkedIn authorization-policy journey. Named hard-coded hosts are intercepted only in an isolated test subprocess with a local CONNECT proxy; do not install a production transport override to enable the fixture. user_claims_named_driver_e2e_test.go shares that isolated TLS fixture for malformed named-driver JSON. Keep proxy targets fixed, clients bounded and hijacked connections closed; setting a proxy after ProxyFromEnvironment has cached its configuration does not reliably isolate a test in the main process.

Signed UserInfo/JWE, new grants, private_key_jwt, request objects, and a complete OIDC at_hash/c_hash conformance upgrade are separate features.

Validation

Follow the repository testing lifecycle. Focused coverage belongs in internal/jwtutil/ed25519_test.go, OAuth's ed25519_test.go, jwks_store_test.go, provider_lifecycle_test.go, shutdown_test.go, and shared provider config tests. Keep the existing KMS signing/default/refresh/export tests passing when changing the shared adapter.

Parser unit tests and executable examples belong in pkg/idp/oauth/parser and pkg/idp/parser, in package parser_test. Cover complete grammar, exact token boundaries, duplicate aliases/states, redacted errors, immutable inputs, driver defaults, static key files, and issuer/audience serialization. Root config_oauth_identity_provider_test.go verifies parsed provider registration and configuration reload.

pkg/authn/oauth_ed25519_e2e_test.go imports the shared public parser and reloads its serialized output before exercising the public provider dispatcher, local TLS OIDC endpoints, real state/nonce/PKCE code exchange, a portal with a temporary local database, and an authorization gatekeeper. The fixture signs upstream JWTs independently with standard-library crypto and uses unrelated portal keys. It covers discovery/static/combined sources, opaque UserInfo, verified access claims, signing compatibility, failures, and rollover. Local self-signed TLS configuration is fixture-only. Use fresh browser sessions and subjects where caches could obscure verification; stop listeners and workers.

pkg/authn/oauth_config_e2e_test.go uses that fixture to verify explicit and discovered issuers, exact issuer matching, static-only behavior, explicit issuer overrides, optional access-token audience/issuer rejection without role leakage, and the existing azp fallback only when access audience is omitted. ID-token audience remains the client ID. Check both successful protected-resource access and absence of portal credentials after rejected identity tokens.

make test TEST_DIR='./internal/jwtutil ./pkg/idp/... ./pkg/kms' COVERAGE_DIR='.coverage/oauth-core'
make test TEST_DIR='./pkg/idp/... ./pkg/authn .' TEST='Test(NewOAuthIdentityProvider|OAuthIdentityProvider|ConfigOAuthIdentityProvider|E2EOAuth)|ExampleNewOAuthIdentityProvider' COVERAGE_DIR='.coverage/oauth-directives'
make test TEST_DIR='./pkg/authn' TEST='^TestE2EOAuth' COVERAGE_DIR='.coverage/oauth-e2e'
COVERAGE_DIR=.coverage/oauth-jwks-fuzz python3 assets/scripts/test_guard.py run \
  go test -mod=readonly -race ./pkg/idp/oauth -run '^$' -fuzz '^FuzzOAuthJwks$' -fuzztime=10000x -parallel=2
make ci-check

Keep protocol/JWKS fuzzing bounded and test network refresh/coalescing separately. Verify both successful login and rejection boundaries through E2E; configuration-only tests do not establish static-key runtime support.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

authdb

無料

Maintain the standalone cmd/authdb server, pkg/httpserver listener and portal routing, HTTP configuration parser, TLS, shutdown, executable tests, and deployment guidance. Use authdbctl for the management client.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

authdbctl

無料

Maintain cmd/authdbctl commands, flags, configuration, terminal input, management retries, output, and executable E2E tests. Use authentication-client for the reusable portal login protocol.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain or embed pkg/authclient for portal login, password/TOTP and API-key authentication, native credential transport, configuration parsing, and credential files. Covers authdbctl login wiring; management commands and the admin API have separate owners.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain conditional authentication challenge policies, reusable authchal and user-transform FromDirectives parsers, safe claim substitution, GitHub ID/organization transforms, registered-factor inventory, passwordless WebAuthn selection, verified AMR access claims, and policy revalidation across portal login, refresh, OIDC, and direct authentication.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain portal cookie configuration, reusable cookie directive parsing, common prefixes and explicit names, domain attributes, factory issuance/deletion, and cookie interoperability with OIDC, refresh, OAuth, and gatekeepers.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

Maintain optional cross-device portal login, its directive parser, QR and polling UI, approving-browser binding, single-use transfers, MFA and provider evidence, logout invalidation, and TLS/browser tests.

日本語の概要は準備中です。原文の説明を表示しています。

greenpau/go-authcrunch602026年10月11日 更新

greenpau のスキルをすべて見る

このスキルの問題を報告する