Skip to content

Latest commit

 

History

10 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cl-rfc8628

The OAuth 2.0 device authorization grant (RFC 8628) as a small CLOS protocol.

The library defines a device authentication client with injected transport, clock, sleep, and browser effects, a credential store protocol, unverified JWT claim readers, and exact-string secret redaction. Providers subclass the RFC 8628 client to validate provider-specific token claims, resolve account identity, and publish credentials through their own stores. Proprietary device flows can subclass the base client and reuse the same transport and failure protocol.

Systems and package

  • ASDF system: cl-rfc8628
  • Test system: cl-rfc8628/tests
  • Package: CL-RFC8628
  • Nickname: RFC8628

Install the locked dependencies and run all tests:

./script/bootstrap
./script/check

The device flow

(defclass portal-client (rfc8628:rfc8628-device-authentication-client)
  ())

(rfc8628:device-authentication-login
 (make-instance 'portal-client
                :issuer "https://portal.example"
                :client-id "public-client-id"
                :device-code-path "/oauth2/device/code"
                :token-path "/oauth2/token"
                :scope "openid offline_access"
                :request-function #'rfc8628:device-authentication-request
                :poll-function #'rfc8628:rfc8628-device-authentication-poll-for-tokens)
 manager)

DEVICE-AUTHENTICATION-LOGIN requests a device code, displays the verification URL and user code, optionally opens the browser, polls through authorization_pending and slow_down responses, validates the token document, and publishes OAUTH-CREDENTIALS through the manager’s primary source. Failures signal DEVICE-AUTHENTICATION-ERROR carrying a stage, an optional HTTP status, and a redacted OAuth error code.

Provider hooks

  • RFC8628-DEVICE-AUTHENTICATION-AUTHORIZATION-CLASS names the pending authorization class.
  • RFC8628-DEVICE-AUTHENTICATION-VALIDATE-TOKEN-RESPONSE rejects token documents missing provider-specific claims.
  • RFC8628-DEVICE-AUTHENTICATION-ACCOUNT-ID resolves the stable account identity, by default from the OpenID or access token subject.
  • RFC8628-DEVICE-AUTHENTICATION-PUBLISH-CREDENTIALS persists approved credentials, by default through the primary source.

Host hooks

  • *SECRET-REGION-FUNCTION* wraps every code path holding secret material, for hosts with credential-scoping machinery.
  • *USER-AGENT-FUNCTION* names the client on the wire.
  • *DEVICE-AUTHENTICATION-ERROR-CLASS* substitutes a condition subclass joining the host’s own hierarchy.

Store protocol

Implement CREDENTIAL-SOURCE-LOAD, CREDENTIAL-SOURCE-SAVE, CREDENTIAL-SOURCE-PATHNAME, and CREDENTIAL-SOURCE-LABEL for private storage. Loads must reread current storage. Implement durable atomic publication in the source; managed acquisition ignores the save result.

CREDENTIAL-MANAGER is the minimal store protocol for device flows. Subclass MANAGED-CREDENTIAL-MANAGER to add credential acquisition and refresh coordination. Supply :primary-source and, optionally, :bootstrap-source. Override CREDENTIAL-MANAGER-REFRESH-EXCHANGE to exchange a refresh token. Return two values: refreshed credentials and whether to publish them. Return false for the second value when another process already published the rotation. Name the service and login action with CREDENTIAL-MANAGER-PROVIDER-LABEL and CREDENTIAL-MANAGER-LOGIN-HINT.

Use CALL-WITH-CREDENTIALS or WITH-CREDENTIALS to acquire credentials and invoke a callback inside *SECRET-REGION-FUNCTION*. Acquisition rereads the primary source, imports only a valid bootstrap access token when the primary source is absent, and refreshes expiring credentials. Concurrent refresh callers share one exchange and one immutable success or failure. An abandoned leader releases waiters to retry. Coordination is local to one manager in one SBCL process; source implementations own cross-process serialization. Managers retain paths and account identity, not tokens.

CREDENTIAL-MANAGER-ACCEPT-ACCOUNT pins the first account and rejects changes unless called with :allow-change t. After a provider-specific reused-token error, call CREDENTIAL-MANAGER-NEWER-ROTATION with the attempted token to reread and validate a newly stored rotation.

Failures signal CREDENTIAL-ERROR, CREDENTIALS-UNAVAILABLE, or TOKEN-REFRESH-FAILED. Hosts can select matching condition classes with *CREDENTIAL-ERROR-CLASS*, *CREDENTIALS-UNAVAILABLE-CLASS*, and *TOKEN-REFRESH-FAILED-CLASS*. Preserve their initialization arguments and exclude secret-bearing values from errors returned by an exchange.

License

COLL-Attribution. See LICENSE.lisp.

About

The OAuth 2.0 device authorization grant (RFC 8628) as a small CLOS protocol

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages