This is a rewrite of the ajmyyra/ambassador-auth-oidc project.
An AuthService is an HTTP Server that an API Gateway (eg Ambassador, Envoy) asks if an incoming request is authorized.
For more information, see this article.
OpenID Connect (OIDC) is an authentication layer on top of the OAuth 2.0 protocol. As OAuth 2.0 is fully supported by OpenID Connect, existing OAuth 2.0 implementations work with it out of the box.
Currently it only supports OIDC's Authorization Code Flow, similar to OAuth 2.0 Authorization Code Grant.
For more details on how various aspects of the AuthService are designed, see the design doc for the relevant section:
The AuthService contains two server processes.
- The Judge Server, which is used for communication with the proxy asking if a request is allowed. The proxy (Envoy, Ambassador, ...) will make a request, with the same method and headers as the request it wants to ask about, at the Judge Server. If the request is authenticated, the Judge Server replies with 200 and the original request is forwarded upstream. If the request is forbidden, the authservice will reply with a redirect to initiate the OIDC login.
- A web server, to host necessary endpoints that need to be accessible to the user. These endpoints include the OIDC client redirect URL, the logout endpoint and helper HTML pages.
Following environment variables are used by the software.
Compulsory
Setting | Description |
---|---|
OIDC_PROVIDER |
URL to your OIDC provider. AuthService expects to find information about your OIDC provider at OIDC_PROVIDER/.well-known/openid-configuration , and will use this information to contact your OIDC provider and initiate an OIDC flow later on. |
AUTHSERVICE_URL_PREFIX |
AuthService expects end users will be able to access its Web-based UI from the outside world at AUTHSERVICE_URL_PREFIX . Usually, it's in the form of <APP_URL>/authservice/ It expects that your API Gateway will route any URL that starts with AUTHSERVICE_URL_PREFIX to it, so it can expose its default Web-based UI and API endpoints. AuthService will use this value to auto-generate sane defaults for a number of settings, including HOMEPAGE_URL , LOGOUT_URL , and AFTER_LOGOUT_URL . The default value, /authservice/ will work out of the box with an Istio VirtualService specifying /authservice/ as its prefix . |
CLIENT_ID |
AuthService will use this Client ID when it needs to contact your OIDC provider and initiate an OIDC flow. |
CLIENT_SECRET |
AuthService will use this Client Secret to authenticate itself against your OIDC provider in combination with CLIENT_ID when attempting to access your OIDC Provider's protected endpoints |
Optional
Setting | Default | Description |
---|---|---|
REDIRECT_URL |
AUTHSERVICE_URL_PREFIX/oidc/callback |
AuthService will pass this URL to the OIDC provider when initiating an OIDC flow, so the OIDC provider knows where it needs to send the OIDC authorization code to. It defaults to AUTHSERVICE_URL_PREFIX/oidc/callback . This assumes that you have configured your API Gateway to pass all requests under a hostname to Authservice for authentication. |
OIDC_AUTH_URL |
<empty> |
AuthService will initiate an Authorization Code OIDC flow by hitting this URL. Normally discovered automatically through the OIDC Provider's well-known endpoint. |
CLIENT_NAME |
AuthService |
A user-visible description for AuthService as an OIDC Client. It is recommended that you set it to a user-visible name for the application/domain that AuthService protects, e.g., MyApp . AuthService will not use this as part of contacting your OIDC Provider, but it will use it to auto-generate user-visible message in the frontend. , e.g., "You are now logged out of MyApp. Click here to log in again." |
OIDC_SCOPES |
openid,email |
Comma-separated list of scopes to request access to. The openid scope is always added. |
AUDIENCES |
istio-ingressgateway.istio-system.svc.cluster.local |
Audiences that the authservice identifies as. Used for authenticators that support audience-scoped tokens. Currently, that is only the Kubernetes authenticator. The default value assumes that the authservice is used at the Istio Gateway in namespace istio-system . |
SERVER_HOSTNAME |
<empty> |
Hostname to listen for judge requests. This is the server that proxies contacts to ask if a request is allowed. The default empty value means all IPv4/6 interfaces (0.0.0.0, ::). |
SERVER_PORT |
8080 |
Port to listen to for judge requests. This is the server that proxies contacts to ask if a request is allowed. |
SKIP_AUTH_URLS |
<empty> |
Comma-separated list of URL path-prefixes for which to bypass authentication. For example, if SKIP_AUTH_URL contains /my_app/ then requests to <url>/my_app/* are allowed without checking any credentials. Contains nothing by default. |
CA_BUNDLE |
<empty> |
Path to file containing custom CA certificates to trust when connecting to an OIDC provider that uses self-signed certificates. |
AFTER_LOGIN_URL |
<originally visited url> |
URL to redirect the user to after they login. Defaults to the URL that the user originally visited before they were redirected for login. For example, if a user visited <app_url>/example and were redirected for login, they will be redirected to /example after login is complete. |
HOMEPAGE_URL |
AUTHSERVICE_URL_PREFIX/site/homepage |
Homepage of the application that can be accessed by anonymous users. |
AFTER_LOGOUT_URL |
AUTHSERVICE_URL_PREFIX/site/homepage |
URL to redirect the user to after they logout. This option used to be called STATIC_DESTINATION_URL . For backwards compatibility, the old environment variable is also checked. |
VERIFY_AUTH_URL |
AUTHSERVICE_URL_PREFIX/verify |
Path to the /verify endpoint. This endpoint examines a subrequest and returns 204 if the user is authenticated and authorized to perform such a request, otherwise it will return 401 if the user cannot be authenticated or 403 if the user is authenticated but they are not authorized to perform this request. |
AUTH_HEADER |
Authorization |
When the AuthService logs in a user, it creates a session for them and saves it in its database. The session secret value is saved in a cookie in the user's browser. However, for programmatic access to endpoints, it is better to use headers to authenticate. The AuthService also accepts credentials in a header configured by the AUTH_HEADER setting. |
ID_TOKEN_HEADER |
Authorization |
When id token is carried in this header, OIDC Authservice verifies the id token and uses the USERID_CLAIM inside the id token. If the USERID_CLAIM doesn't exist, the authentication would fail. |
LOG_LEVEL |
"INFO" | Set the log level to one of "FATAL", "ERROR", "WARN", "INFO", or "DEBUG" to specify the verbosity of the OIDC-Authservice logs. |
The AuthService provides a web server with some defaults pages for a homepage
and an after_logout
page. The following values are about these pages. To
learn more about how these pages work, see the templating guide.
By default, this web server listens at port 8082
and its endpoints are:
Endpoint | Description |
---|---|
/site/homepage |
Landing page |
/site/after_logout |
After Logout page |
/site/themes |
Themes |
To expose the web server in an environment like Kubernetes with Istio, you need to:
- Create a Service pointing to the AuthService's web server port (8082).
- Create an Istio VirtualService to match traffic with the
$AUTHSERVICE_URL_PREFIX
path-prefix and direct it to the Service you created. Usually, theAUTHSERVICE_URL_PREFIX
is in the form of<url>/<path>
(e.g,.<url>/authservice
). Make sure your VirtualService captures requests with the<path>
.
Setting | Default | Description |
---|---|---|
TEMPLATE_PATH |
web/templates/default |
A comma-separated list of dirs to look under for templates. Templates with the same name override previously registered ones. For more information, see the templating guide. It always contains the default templates. |
CLIENT_NAME |
AuthService |
A human-readable name for the client. Used in the web server's pages. |
THEMES_URL |
themes |
URL where the themes are served. Theme assets are found under THEMES_URL/THEME . To learn how you can create your own theme, see the templating guide. |
THEME |
kubeflow |
Path under THEMES_URL where the theme assets are served. |
TEMPLATE_CONTEXT_<key> |
empty |
Variables that will end up in the user-defined map in the template context. For example, if you define TEMPLATE_CONTEXT_KEY=VALUE , then a KEY: VALUE entry will be added to the user-defined map in the template context. Used to pass values to site templates and allow for further customization. |
OIDC-AuthService stores sessions and other state in a local file. The users can select between using BoltDB which is the default option or redis for the session store. Session store-related settings:
Setting | Default | Description |
---|---|---|
SESSION_STORE_PATH |
"/var/lib/authservice/data.db" | Path to local session store. Backed by BoltDB. |
OIDC_STATE_STORE_PATH |
"/var/lib/authservice/oidc_state.db" | Path to the session store used to save the sessions for the OIDC state parameter. |
SESSION_MAX_AGE |
"86400" | Time in seconds after which sessions expire. Defaults to a day (24h). |
SESSION_SAME_SITE |
"Lax" | SameSite attribute of the session cookie. Check details of SameSite attribute here. Its value can be "None", "Lax" or "Strict". |
SESSION_STORE_TYPE |
"boltdb" | Set SESSION_STORE_TYPE to either "boltdb" to use BoltDB as the session store, "redis" to use redis as the session store, or "redisfailover" if you are running High availability with Redis Sentinel as the session store. Note that only one of the three can be used. Also, if you select redis or redisfailover and depending on your redis configurations, you might need to set the password and the number of the database that OIDC-AuthService will use as a redis-client. |
SESSION_STORE_REDIS_ADDR |
"127.0.0.1:6379" | Set the host:port address for the redis session store. |
SESSION_STORE_REDIS_PWD |
"" | Set the password to connect with the redis session store. |
SESSION_STORE_REDIS_DB |
0 | Set the number of the database that AuthService should use. If not configured and if the redis session store is selected, then AuthService will use the default redis database. |
SESSION_DOMAIN |
"" | Domain attribute of the session cookie. Check details of Domain attribute here. If len(SESSION_DOMAIN) > 0 the incoming request's host and scheme are also saved in the state rather than just the path. This enables AuthService to service all subdomains of SESSION_DOMAIN. |
SCHEME_DEFAULT |
https |
Default scheme for incoming requests. |
SCHEME_HEADER |
<empty> |
Header to use for incoming request scheme. If ommitted or header is not present in request, SCHEME_DEFAULT will be used instead. |
By default, the AuthService keeps sessions to check if a user is authenticated. However, there may be times where we want to check a user's logged in status at the Provider, effectively making the Provider the one keeping the user's logged in status to enable access revocation scenarios and centralized management.
Setting | Default | Description |
---|---|---|
STRICT_SESSION_VALIDATION |
false |
Be strict about session validity by quering the OIDC provider for the validity of the token at each individual request, by hitting the userinfo endpoint. This ensures the authservice can detect an OIDC token has been revoked on the OIDC provider immediately, and destroy its own session. However, it may increase the load on the OIDC provider and introduces additional latency. Disabled by default, enable with "on" OR "true". |
OIDC AuthService can add extra headers based on the userid that was detected. Applications can then use those headers to identify the user.
Setting | Default | Description |
---|---|---|
USERID_CLAIM |
"email" | Claim whose value will be used as the userid (default email ). |
GROUPS_CLAIM |
"groups" | Claim whose value will be used as the user's groups (default groups ) |
USERID_HEADER |
"" | Name of the header containing the user-id to be added to the upstream request. Header omitted if unset |
USERID_PREFIX |
"" | Prefix to add to the userid, which will be the value of the USERID_HEADER . |
USERID_TRANSFORMERS |
"" | List of transformations for the userid value (from USERID_CLAIM ) in JSON format [{"matches": "regex", "replaces": "value"}, ...] . OIDC AuthService will evaluate the transformation rules in order and if the matches pattern matches the userid, the match is replaced by the replaces value. If multiple rules match, only the first one is applied and if no rule matches the userid, the original userid will be used. For the matches regular expression, use the standard golang syntax (more info). Note that a regular expression is a string and the \ must be escaped (using \\ ). For example using USERID_TRANSFORMERS = '[{"matches": "user@domain\\.com$", "replaces": "internal"}, {"matches": "@domain\\.com$", "replaces": ""}]' , AuthService will do the following transformation: user@domain.com -> internal and another@domain.com -> another . |
GROUPS_HEADER |
"" | Name of the header containing the groups to be added to the upstream request. Header omitted if unset |
AUTH_METHOD_HEADER |
"Auth-Method" | Name of the header that is included in the proxied requests to inform the upstream app about the authentication method used (cookie / header ). |
TOKEN_HEADER |
"Authorization" | Name of the header containing user id token (JWT) that will be added to the upstream request. |
TOKEN_SCHEME |
"Bearer" | Authorization scheme (e.g. Bearer, Basic) used for user id token. |
SESSION_JWTCOOKIE |
"" | When not empty, this is the name of the cookie set to the JWT |
OIDC AuthService can authenticate clients based on the bearer token found in the Authorization header of their request. It caches the bearer token and the respective user information. If the incoming request has a cached bearer token then AuthService authenticates this client and proceeds with the basic authorization checks. The following settings are related to the caching mechanism:
Setting | Default | Description |
---|---|---|
CACHE_ENABLED |
false |
Set CACHE_ENABLED to true to enable caching. |
CACHE_EXPIRATION_MINUTES |
5 (minutes) |
Set the CACHE_EXPIRATION_MINUTES value to define how many minutes it takes for every cache entry to expire. |
By default, OIDC AuthService attempts to authenticate client requests with each one of the available authentication methods that it supports. In certain use cases the admins may want to skip the checks performed by one or more of the authentication methods. OIDC AuthService can be configured to skip a particular authentication method via the following configurations:
Setting | Default | Description |
---|---|---|
IDTOKEN_AUTHN_ENABLED |
true |
Set IDTOKEN_AUTHN_ENABLED to false to disable the ID token authentication method. |
KUBERNETES_AUTHN_ENABLED |
true |
Set KUBERNETES_AUTHN_ENABLED to false to disable the Kubernetes authentication method. |
ACCESS_TOKEN_AUTHN_ENABLED |
true |
Set ACCESS_TOKEN_AUTHN_ENABLED to false to disable both the access token authentication methods. |
ACCESS_TOKEN_AUTHN |
"jwt" | Set ACCESS_TOKEN_AUTHN to either "jwt" to enable the JWT access token authentication method, or "opaque" to enable the opaque access token authentication method. Note that only one of the two access token authentication methods can be used. |
OIDC AuthService can also perform basic authorization checks. The following settings are related to authorization:
Setting | Default | Description |
---|---|---|
GROUPS_ALLOWLIST |
"*" | List of groups that are allowed to pass authorization. By default, all groups are allowed. If you change this option, you may want to include the system:serviceaccounts group explicitly, if you need the AuthService to accept ServiceAccountTokens. |
EXTERNAL_AUTHZ_URL |
"" | Use an external authorization service. This option is disabled by default, to enable set the value to the target external authorization service (e.g. EXTERNAL_AUTHZ_URL=http://authorizer/auth ). If you have enabled this option then for a request to be authorized, both the group and the external authorization service will have to allow the request. |
This authentication is similar to the JWT auth, except that it will use the JWT in a specific cookie. This auth is disabled by default. Options to enable it:
Setting | Default | Description |
---|---|---|
JWTFROMEXTRAPROVIDER_AUTHN_ENABLED | false |
Set to true to enable this auth |
JWTFROMEXTRAPROVIDER_PROVIDER_URL | "" | Set to the oidc provider url |
JWTFROMEXTRAPROVIDER_ISSUER | `` | The issuer |
JWTFROMEXTRAPROVIDER_ISSUERNAME | `` | The issuer name |
JWTFROMEXTRAPROVIDER_COOKIE_NAME | "" | Set to the cookie name where the JWT is set |
JWTFROMEXTRAPROVIDER_CLIENTID | "" | Set to the clientID the jwt should have |
JWTFROMEXTRAPROVIDER_SETHEADER | "" | Set the HTTP header to the JWT value. Empty to not set any header |
OIDC-Authservice is an OIDC Client, which authenticates users with an OIDC Provider and assigns them a session. Can be used with:
- Ambassador with AuthService
- Envoy with the ext_authz Filter
- Istio with EnvoyFilter, specifying ext_authz
- Local:
make build
- Docker:
make docker-build
For E2E tests, we use K3d, a very lightweight way to run a K8s cluster locally using Docker. For E2E tests to work, you need the following external tools:
go (>=1.13)
kustomize
kubectl
k3d
You can use make bin/deps
to install them locally under ./bin/deps
. Then
simply run make e2e
.