beffroi/oidc knows no HTTP, no database and no container. What it needs of the outside it asks through a
port: an interface of Beffroi\Oidc\Port, one capability each, with the few methods that capability needs and
the exceptions an implementation may throw written in its contract. A use case is given the ports it calls
and no other.
The bundle answers every port. An integration outside Symfony answers them
itself, and starts from the implementations the package ships, below.
Besides its own, the package uses eighteen ports of the core, Beffroi\Core\Port:
it calls sixteen and implements two. And it calls two interfaces of the PHP-FIG, the clock of PSR-20, which
the use cases read the time from, and the event dispatcher of PSR-14, which every act leaves through.
Port of the core
What the protocol does with it
RandomnessInterface
Draws every value it hands out and recognises later: codes, tokens, references, user codes
UuidGeneratorInterface
Names what it records, grants, consents and families of refresh tokens among them, and the jti of a logout token
JwsSignerInterface
Signs what the tenant issues: ID tokens, at+jwt, logout tokens, signed UserInfo, introspection and authorization responses
JwsVerifierInterface
Verifies what the tenant signed and is handed back: an at+jwt, an id_token_hint
The secrets of the clients, hashed when they are kept and read back by the algorithm they name
SecretSealerInterface
Seals what nobody but the provider may read: the person an at+jwt of a token exchange or of a JWT bearer grant is about, and the references a backchannel request keeps for the client it calls back
KeyBoundArtifactInterface, implemented
Six kinds of document bound to a key of the tenant, the ID token, the at+jwt, the logout token, the signed authorization response, the pushed request and the request object encrypted to it, each declaring how long a retiring key stays published for it
ArchiveChapterInterface, implemented
The two chapters the protocol adds to the archive of a person: the consents, and what each client was given
What the clients of a tenant registered, read as a set: whether every one pushes its requests, which shapes of access token and which resources and scopes they take, whether one reads unsigned request objects
Each of these remembers something between two requests, and is meant to be shared by every worker of a
deployment: a replay on another worker is a replay all the same, and a budget is the budget of the whole
deployment.
Port
What it remembers
In the bundle
ClientAssertionReplayGuardInterface
The jti of a client assertion until it expires (RFC 7523 §3)
The cache pool beffroi.client_assertions
IssuerAssertionReplayGuardInterface
The jti of an assertion a trusted issuer signed, until it expires
beffroi.issuer_assertions
RequestObjectReplayGuardInterface
The jti of a request object until it expires (CIBA Core §7.1.1)
beffroi.request_objects
SoftwareStatementReplayGuardInterface
The jti of a software statement until it expires (RFC 7591 §2.3)
beffroi.software_statements
DpopProofReplayGuardInterface
The jti of a DPoP proof, per key, for as long as the proof stands (RFC 9449 §11.1)
beffroi.dpop
DpopNonceInterface
Whether a proof must carry a nonce, and whether the one it carries is current (RFC 9449 §8)
beffroi.dpop when nonces are required, nothing otherwise
ClientJwksCacheInterface
The keys read back from a jwks_uri, with when they were read
beffroi.client_keys, and beffroi.issuer_keys for trusted issuers
ClientLoadBudgetInterface
What an authenticated client may still ask in the window
A rate limiter on beffroi.load
The bundle declares each pool on cache.app, in a pool of its own, so that a deployment points one at a
shared store without touching the rest of its cache.
Telling a person that a backchannel request waits for them
A message on the lane of the notifications
LogoutTokenDeliveryInterface
The budget a logout token is written for, which its exp and the retirement of its signing key read. It bounds the token and not the sending: a send that comes after it carries an expired token
The waits of the retry policy of that lane and the timeout of the sender, from back_channel_logout
The rest are the ports through which the provider learns what it is wired with, which is what it serves and
what it announces at once. Most of them are answered by the module itself, out of the classes the
integration tags: a grant, a client authentication method, a shape of access token, a kind of subject
identifier is a class and a line of wiring, and the port that lists them is never a list kept beside it.
Port
What it lists
Answered by
ServedGrantsInterface
The grants the token endpoint serves, and what each one does
The module, over the tagged grants
ClientAuthenticationMethodsInterface
The client authentication methods, in the order they are tried
The package carries the implementations that need nothing but its own dependencies, under
Beffroi\Oidc\Bridge:
Namespace
What is in it
Configuration
The clients, the registration policy and the trusted issuers, read from what a deployment declares and validated when it starts
JwtLibrary
The reader of a compact JWT, the verifier of a client's signature, of a DPoP proof and of a client_secret_jwt MAC, and the JWE encrypter, on web-token/jwt-library
Pki
The reader of a client certificate, on spomky-labs/pki-framework
Null
NoDpopNonce, the provider that asks no nonce of a proof
InMemory
The stores, the replay guards, the cache of the keys of a client and a pairwise salt, for tests and examples: nothing in them survives the process
The stores that outlive a request, the router, the HTTP client and the lanes are the integration's, which is
what the bundle provides.