Gafaelfawr uses structlog (via Safir) to log all its internal messages in JSON. It is run via uvicorn, which also logs all requests in the standard Apache log format. Interesting events that are not obvious from the access logging done by uvicorn are logged at the INFO level. User errors are logged at the WARNING level. Gafaelfawr or other identity management errors are logged at the ERROR level.

Log attributes

The main log message will be in the event attribute of each log message. If this message indicates an error with supplemental information, the additional details of the error will be in the error attribute.

Gafaelfawr will add some consistent attributes to log messages, in addition to the default attributes added by Safir. All authenticated routes add the following attributes once the user’s token has been located and verified:


The scopes of the authentication token.


The key of the authentication token.


Where the token was found. Chosen from cookie (found in the session cookie), bearer (provided as a bearer token in an Authorization header), or basic-username or basic-password (provided as the username or password in an HTTP Basic Authorization header).


The username of the token.

The /auth route adds the following attributes:


The URL being authenticated. This is the URL (withough the scheme and host) of the original request that Gafaelfawr is being asked to authenticate via a subrequest. This will be NONE if the request was made directly to the /auth endpoint (which should not happen in normal usage, but may happen during testing).


The list of scopes required, taken from the scope query parameter


The authorization strategy, taken from the satisfy query parameter.

The /login route adds the following attributes:


The URL to which the user will be sent after successful authentication.

Routes that create or modify tokens will log the new details of the token in some or all of the following attributes:


The expiration time of the token, in ISO 8601 format but with the T separator replaced with a space.


The key of the new token.


The name of the token.


The scopes of the newly-created token (not to be confused with scopes, which are the scopes of the token used to authenticate the request).


The service for which this delegated token was created, used only for internal tokens.


User identity information stored with the token. This information will override any information coming from external sources, such as LDAP or Firestore. It is a dictionary, with possible keys including name, email, uid, gid, and groups.


The username of the new token. This is often omitted when a user is creating a token for themselves, and the username of the token therefore matches user.