Discovery

✓ S101 Profile URL is valid and can be fetched Fetched with HTTP 200.
✓ S102 Advertises indieauth-metadata Found https://indiko.dunkirk.sh/.well-known/oauth-authorization-server in the HTML.
✓ S103 Link header and HTML agree Only one of them is present.
✓ S104 Metadata is a JSON document HTTP 200 with a JSON object.
✓ S105 Issuer identifier is valid issuer is https://indiko.dunkirk.sh
✓ S106 Authorization endpoint is listed authorization_endpoint is https://indiko.dunkirk.sh/auth/authorize
✓ S107 Token endpoint is listed token_endpoint is https://indiko.dunkirk.sh/auth/token
✓ S108 Introspection endpoint is listed introspection_endpoint is https://indiko.dunkirk.sh/auth/token/introspect
✓ S109 PKCE S256 is supported S256 is listed.
✓ S110 Advertises the iss response parameter authorization_response_iss_parameter_supported is true.
✓ S111 Lists supported scopes scopes_supported lists openid, profile, email, offline_access
✓ S112 Response and grant types are consistent Consistent (or using the defaults).
✓ S113 Revocation needs no client authentication revocation_endpoint_auth_methods_supported is ["none"].
✓ S114 Metadata can be read by browser-based apps Access-Control-Allow-Origin: *
✓ S115 Legacy endpoint links match the metadata Legacy links match the metadata.
✓ S116 Endpoints use https All endpoints use https.
✓ S117 Serves metadata at the RFC 8414 well-known URL Served at https://indiko.dunkirk.sh/.well-known/oauth-authorization-server with the same issuer.

Authorization requests

✓ S201 Returns state unmodified state was returned unmodified.
✓ S202 Returns the iss parameter iss matched the issuer on every redirect.
✓ S203 Issues an authorization code A code was issued.
✓ S204 Keeps the query string of the redirect URI The query string of the redirect URI was kept.
✓ S205 Fetches client information Your server fetched the client_id document.
✓ S206 Consent screen identifies the application The approval screen showed the application name and client_id.
✓ S207 Reports a denied request to the client Cancelling returned error=access_denied.
✓ S208 Refuses an unregistered cross-origin redirect URI Your server showed an error and did not redirect.
✓ S209 Accepts a registered cross-origin redirect URI The registered cross-origin redirect URI was used.
✓ S210 Matches redirect URIs exactly Your server showed an error and did not redirect.
✓ S211 Is not fooled by credentials in a URL Your server showed an error and did not redirect.
✓ S212 Ignores client metadata for a different client_id Your server showed an error and did not redirect.
✓ S213 Rejects a repeated redirect_uri parameter Your server showed an error and did not redirect.
✓ S214 Is not an open redirector Your server showed an error and did not redirect.
✓ S215 Requires PKCE Your server refused the request with error=invalid_request.
✓ S216 Refuses the plain PKCE method Your server refused the request with error=invalid_request.
✓ S217 Refuses the implicit flow Your server refused the request with error=unsupported_response_type.
✓ S218 Handles a missing state parameter Your server refused the request with error=invalid_request.
✓ S219 Refuses an invalid client_id Your server showed an error.
✓ S220 Does not trust the me parameter Your server returned https://dunkirk.sh/ rather than the profile URL the request asked for.
✓ S221 Refuses a PKCE method without a challenge Your server refused the request with error=invalid_request.
✓ S222 Refuses a challenge without a method Your server refused the request with error=invalid_request.

Code redemption

✓ S301 Exchanges a code at the token endpoint The code was exchanged for tokens.
✓ S302 Codes can only be used once The used code was refused (HTTP 400 invalid_grant).
✓ S303 Reusing a code revokes its tokens The tokens issued for the code were revoked when it was replayed.
✓ S310 Refuses a wrong code_verifier The wrong verifier was refused (HTTP 400 invalid_grant).
✓ S311 Refuses a missing code_verifier Refused (HTTP 400 invalid_request).
✓ S312 Refuses a code presented by another client Refused (HTTP 400 invalid_grant).
✓ S313 Refuses a mismatched redirect_uri Refused (HTTP 400 invalid_grant).
✓ S320 Exchanges a code without a scope Returned me (https://dunkirk.sh/) and no access token.
✓ S330 Refuses an unknown code Refused with HTTP 400 invalid_grant.
✓ S331 Refuses missing or unsupported grant types Refused with invalid_request and unsupported_grant_type.
✓ S332 Errors are JSON with an error code Error responses are JSON with an error code.
✓ S333 Token endpoint refuses GET requests GET requests are refused (HTTP 405 invalid_request).
✓ S334 Token endpoint supports CORS preflight Preflight allowed for *.

Token responses

✓ S401 Token response is JSON HTTP 200 with a JSON object.
✓ S402 Includes an access token An access token was issued.
✓ S403 Token type is Bearer token_type is Bearer.
✓ S404 Returns a valid me me is https://dunkirk.sh/
✓ S405 The returned me is verified me matches a URL seen during discovery.
✓ S406 Token responses are not cached Cache-Control: no-store is set.
✓ S407 Says when the token expires expires_in is 3600 seconds.
✓ S408 Reports the granted scope scope is "profile".
✓ S409 Profile information is well formed The profile object is well formed.
✓ S410 Access tokens are hard to guess The access token is long enough.
✓ S420 Access token format Access tokens are opaque strings, which resource servers check by introspection.
– S421 JWT header marks it an access token The access token is not a JWT.
– S422 JWT verifies against the published keys The access token is not a JWT.
– S423 JWT claims are complete The access token is not a JWT.

Refresh tokens

✓ S501 Refreshes an access token Refreshing returned a new access token.
✓ S502 Refuses a refresh by another client Refused for a different client_id (HTTP 400 invalid_grant).
✓ S503 Refuses to add scopes on refresh Asking for more scope was refused (HTTP 400 invalid_scope).
✓ S504 Old refresh tokens stop working after rotation The replaced refresh token was refused (HTTP 400 invalid_grant).
✓ S505 Refresh token reuse revokes the grant Reusing the old refresh token revoked the newest tokens too.

Revocation

✓ S601 Revokes an access token Returned HTTP 200.
✓ S602 Revoked tokens stop working The revoked token is refused (HTTP 401 invalid_token).
✓ S603 Revokes a refresh token The revoked refresh token is refused (HTTP 400 invalid_grant).
✓ S604 Revoking an unknown token succeeds Returned HTTP 200.

Userinfo

✓ S701 Returns profile information Returned the profile for https://dunkirk.sh/.
✓ S702 Refuses a request without a token Returned HTTP 401.
✓ S703 Refuses an invalid token Returned HTTP 401 with error="invalid_token".

Introspection

✓ S801 Introspection requires authorization Unauthenticated introspection was refused with HTTP 401.
✓ S802 Refused introspection reveals nothing The refusal reveals nothing about the token.

Security hygiene

✓ S901 Token endpoint requires TLS Plain http requests are not processed (HTTP 301).
✓ S902 Authorization pages cannot be framed Framing is prevented (X-Frame-Options: DENY).
✓ S905 Tokens never appear in URLs No tokens appeared in redirect URLs.
✓ S906 No credentialed wildcard CORS No credentialed wildcard CORS.