Change log¶
1.3.2 (2020-06-08)¶
- Work around an NGINX ingress bug in 1.39.1 by allowing multiple
X-Forwarded-Proto
headers in the incoming request. - Document how to configure NGINX ingress with the official Helm chart to support logging accurate client IPs.
1.3.1 (2020-05-29)¶
This release drops support for Python 3.7. Python 3.8 or later is now required.
- Require Python 3.8 and drop Python 3.7 support.
- Include
token_source
in logs of the/auth
route to record how the client passed in the authentication token. - Set the
X-Auth-Request-Client-Ip
header to the calculated client IP on a successful reply from the/auth
route. - The output from the
/auth/analyze
route is now sorted and formatted to be easier for humans to read and compare. - Include more information in the user-facing error message when a connection to the authentication provider’s callback endpoint fails.
- Report a better error message if the OpenID Connect provider doesn’t have a JWKS entry for the key ID of the identity token.
1.3.0 (2020-05-19)¶
This release changes the construction of identity and groups from GitHub authentication by coercing identifiers to lowercase. GitHub is case-preserving but case-insensitive, which is complex for protected applications to deal with. This change ensures Gafaelfawr exposes a consistent canonical identity to downstream applications that is also compatible with other systems that expect lowercase identifiers, such as Kubernetes namespaces.
- Lowercase GitHub usernames when constructing identity tokens.
- Lowercase GitHub organization names when constructing group membership.
1.2.1 (2020-05-14)¶
Gafaelfawr can now analyze the X-Forwarded-For
header to determine the true client IP for logging purposes.
This requires some configuration of both Gafaelfawr and the NGINX ingress.
See the logging documentation for more information.
- Add new
proxies
setting to configure what network blocks should be treated as internal to the Kubernetes cluster. - Set the client IP to the right-most IP in
X-Forwarded-For
that is not in a network block listed inproxies
. - Document the necessary NGINX ingress configuration for
X-Forwarded-For
analysis to work correctly. - Fall back on logging
X-Original-URL
ifX-Original-URI
is not set. - Stop recommending setting the
auth-request-redirect
annotation and do recommend setting theauth-method
annotation.
1.2.0 (2020-05-07)¶
New in this release is an /auth/forbidden
route that can be used to provide a non-cached 403 error page.
See the documentation for more information.
This release changes Gafaelfawr’s logging format and standardizes the contents of the logs. All logs are now in JSON. See the new logging documentation for more information.
- Default to JSON logging (controlled via
SAFIR_PROFILE
) - Add remote IP and
User-Agent
header field values to all logs. - Add more structured information to authentication logging.
- Ensure each route logs at least one event.
1.1.1 (2020-04-29)¶
- Include any errors from the external OpenID Connect provider in the error message if retrieving an ID token fails. Previous versions only reported a generic error message, which was missing error details from the JSON body of the upstream error, if available.
1.1.0 (2020-04-28)¶
This release overhauls configuration parsing and removes use of Dynaconf. As a result, the top-level environment key in configuration files is no longer required (or supported). All configuration settings should now be at the top level.
This release also adds support for specifying the type of authentication challenges to unauthenticated users.
- Replace Dyanconf with pydantic for configuration parsing. This should produce much better diagnostics for invalid configuration files. This also eliminates the Dynaconf environment key that was previously expected to be the top-level key of the configuration file. Existing configuration files will need to be flattened by removing that key and elevating configuration settings to the top level.
- Add support for an
auth_type
parameter to the/auth
route. This can be set tobasic
to request that unauthenticated users be challenged for Basic authentication instead of Bearer. That in turn will cause pop-up authentication prompting in a web browser. - Fix syntax of
WWW-Authenticate
challenges and return them in more cases. Attempt to properly implement RFC 6750, including using propererror
attributes, including challenges in some 400 and 403 replies, and including thescope
attribute where appropriate. - Return 403 instead of 401 for unauthenticated AJAX requests.
401 triggers the redirect handling in ingress-nginx, but this is pointless for AJAX requests, which cannot navigate the redirect to an external authentication provider.
Worse, AJAX requests may be frequently retried on error (such as an expired credential), which if redirected can create a low-grade denial of service attack on the authentication provider, trigger rate limiting, and cause other issues.
AJAX requests, as detected by
X-Requested-With: XMLHttpRequest
in the request headers, now get a 403 reply if they have missing or expired credentials.
1.0.0 (2020-04-24)¶
JWT Authorizer has been renamed to Gafaelfawr. It is named for Glewlwyd Gafaelfawr, the knight who challenges King Arthur in Pa gur yv y porthaur? and, in later stories, is a member of his court and acts as gatekeeper. Gafaelfawr is pronounced (very roughly) gah-VILE-fahwr.
As of this release, Gafaelfawr supports OpenID Connect directly and no longer uses oauth2_proxy. There are new options to configure the OpenID Connect support.
The configuration has been substantially overhauled in this release and many configuration options have changed names. Please review the documentation thoroughly before upgrading.
- Rename the application to Gafaelfawr and the Python package to gafaelfawr.
- Add native support for OpenID Connect.
- Fix a security weakness where a user could request a token with any known scope, regardless of the scopes of their own authentication token. The scopes of user-issued tokens are now limited to the scopes of the token used to authenticate to the token creation page.
- The
/auth
route now takes ascope
parameter instead of acapability
parameter to specify the scopes required for authorization. - Rename
Capability
toScope
in the headers exposed after successful authorization. - Overhaul how authentication sessions and user-issued tokens are stored in Redis. This will invalidate all existing sessions and user-issued tokens on upgrade. Sessions are now encrypted with Fernet rather than with the complex encryption required for oauth2_proxy compatibility.
- Significantly overhaul the configuration settings.
Delete the unused configuration options
`www_authenticate
,no_authorize
,no_verify
, andset_user_headers
. Eliminate theissuers
setting in favor of configuring the upstream issuer in the OpenID Connect configuration. Rename the configuration settings for the internal issuer. - Always set the
scope
claim when issuing internal tokens, based on group membership, and only check thescope
claim during authorization. - Add a new
/logout
route. - Simplify token verification for internally-issued tokens and avoid needless HTTP requests to the JWKS route.
- Require that all tokens have claims for the username and UID (the claim names are configurable).
- Add
/oauth2/callback
as an alias for the/login
route for backwards compatibility with oauth2_proxy deployments. - Drop support for reading tokens from
X-Forwarded-Access-Token
orX-Forwarded-Ticket-Id-Token
headers. - Protect against open redirects in the
/login
route. The destination URL now must be at the same host as the/login
route. - Add the
generate-key
CLI command to ease generation of a new signing key. - Remove support for configuring secrets directly and only read them from files. It simplifies the code and improves testing to have only one mechanism of secret management.
- Improve logging somewhat (although it’s still not structured or documented).
- Cleanly shut down Redis connections when shutting down the server.
- Add architecture documentation and a glossary of terms to the manual.
- Flesh out the Kubernetes installation documentation and document the standard Helm chart.
0.3.0 (2020-04-20)¶
With this release, JWT Authorizer has been rewritten to use aiohttp instead of Flask.
There are corresponding substantial changes to how the application is started, which are reflected in the Docker configuration.
A new configuration key, session_secret
is now required and is used to encrypt the session cookie (replacing flask_secret
).
- Rewrite using aiohttp and aioredis instead of Flask and redis.
- Add support for GitHub authentication.
This is done via a new
/login
route and support for authentication credentials stored in a cookie. - Add a (partial) manual. The formatted text is published at gafaelfawr.lsst.io. Included are partial installation instructions, a guide to configuration settings, and API documentation.
- Add support for serving
/.well-known/jwks.json
for the internal token signing key, based on the configured private key. A separate static web service is no longer required. - Remove support for authorization plugins and always do authorization based on groups. None of the Rubin Observatory configurations were using this support, and it allows significant code simplification.
- Allow GET requests to
/analyze
and return an analysis of the user’s regular authentication token. - Trust
X-Forwarded-For
headers (primarily for logging purposes). - Remove some unused configuration options.
- Add improved example configuration files in
example
. - Significantly restructure the code to hopefully make the code more maintainable.
- Significantly expand the test suite.
- Support (and test) Python 3.8.
- Change the license to MIT from GPLv3.
0.2.2 (2020-03-19)¶
- Fix decoding of dates in the
oauth2_proxy
session.
0.2.1 (2020-03-18)¶
- Fix misplaced parameter when decoding tokens in the
/auth
route.
0.2.0 (2020-03-16)¶
- Add
/auth/analyze
route that takes a token or ticket via thetoken
POST parameter and returns a JSON analysis of its contents. - Overhaul the build system to match other SQuaRE packages.