Files
NLnetLabs-krill/defaults/krill-multi-user.conf
T
Ximon EighteenandGitHub 0f930f37ef Logout enhancements (closes #385, closes #397, fixes #408, closes #425) (#436)
- Formalize support for different logout strategies and add the fallback strategy.
- Generate the logout URL at logout time in preparation for supporting dynamic logout requests (as needed by token revocation).
- Secure the connection to the mock OpenID Connect provider with a self-signed TLS certificate.
- Allow self-signed certificates for HTTPS connections to localhost (same policy as elsewhere in Krill).
- Upgrade openidconnect-rs to latest v2.0.0 alpha to gain contributed support for OAuth 2.0 Token Revocation. (#385 and #397)
- Use reqwest 0.9.x directly instead of via the openidconnect-rs crate (we cannot use the v0.11.x reqwest that comes with the crate as (a) it doesn't permit self-signed certificates, (b) the blocking implementation was changed to be async which causes problems when inside an existing async runtime, and (c) switching the OpenID Connect client code over to be async is non-trivial - see #428).
- Pass the ID token as `id_token_hint` to the OpenID Connect RP-Initiated Logout 1.0 endpoint. (#408)
- Refined logic for the various logout mechanism permutations. (#425).
- Require OpenID Connection RP-Initiated Logout 1.0 and OAuth 2.0 Token Revocation endpoints to be HTTPS per the specs.
- Passes manual testing with Microsoft Azure Active Directory RP-Initiated Logout support and Google Compute Cloud OAuth 2.0 Token Revocation support.
- Added a Google Cloud Platform example to the comments in the default config file.
- Updated and added tests.
- Fixed logout and token revocation in the mock OpenID Connect provider to actually terminate login sessions.
- Handle a race condition in Lagosta where null user data was accessed that was just deleted due to logout.
- Handle errors from the Krill logout endpoint in Lagosta.
2021-03-08 23:39:45 +01:00

540 lines
28 KiB
Plaintext

######################################################################################
# #
# ----==== WEB UI MULTI-USER LOGIN CONFIGURATION ====---- #
# #
# The settings below can be used to permit multiple users with configurable #
# access rights to login to the Krill web interface. #
# #
######################################################################################
#
# Global auth(entication & authorization) settings
#
# These control which auth provider in Krill will be used to authenticate users
# and settings common to all auth providers. See below for more details.
#
# auth_type = "master-token"
# auth_policy = "..."
# auth_private_attributes = ["...", ...]
# Auth type (optional)
#
# Which provider to use for authentication (AuthN), authorization (AuthZ) and
# identity (ID). Also affects which login form the Krill web UI displays, or
# (in the case of auth_type = "openid-connect") the user is redirected to.
#
# Supported values: "master-token" (default), "config-file" or "openid-connect".
#
# At-a-glance comparison:
# =======================
# Setting Value AuthN AuthZ ID
# ----------------------------------------------------------------------------
# "master-token" auth_token role = "admin" id = "master-token"
# ----------------------------------------------------------------------------
# "openid-connect" provider provider provider
# checked supplied supplied
# ----------------------------------------------------------------------------
# "config-file" values are taken from the [auth_users] section in this
# config file
# ----------------------------------------------------------------------------
#
# NOTE: At present the master-token provider is used as a fallback provider
# when using "openid-connect" or "config-file" as the primary provider. This is
# to ensure that krillc, which uses master-token authentication, is still able
# to communicate with the krill daemon.
#
### auth_type = "master-token"
# Auth policy (optional)
#
# The path to an external authorization policy file (or directory containing
# policy files) to use in addition to the ones built-in to Krill. The files must
# be in Oso Polar format [*1] and are loaded after the built-in Krill policies.
#
# Custom authorization policies are intended to handle requirements that are too
# complex for just the settings available in krill.conf and is an advanced
# topic beyond the scope of this documentation.
#
# The built-in policies treat the following user attributes specially:
#
# - "role" - One of "admin", "readwrite" or "readonly". See the full Krill
# documentation for more information about which permissions are
# associated with each role.
# - "inc_cas" - A comma-separated set of CA handles which should be included
# in the set the user is permitted to see. If present this
# attribute will prevent the user seeing or interacting with any
# CA handle that is not in this set.
# - "exc_cas" - A comma-separated set of CA handles which should be excluded
# from the set the user is permitted to see. Overrides inc_cas.
# If inc_cas is not set, any CA handle NOT in exc_cas will be
# visible to the user who may interact with it according to
# the permissions granted to the user (e.g. through a role
# assignment).
#
# Note: The inc_cas and exc_cas settings only restrict visibility of and
# interaction with specified CAs via the Krill web UI. CA handles are still
# visible in the repository content and metrics output by Krill.
#
# References:
# *1 - https://docs.osohq.com/getting-started/policies/index.html
#
### auth_policy = "..."
# Auth private attributes (optional)
#
# Zero or more user attributes that should not be revealed by (or even sent to)
# the Krill web UI. For example, you may wish to hide "exc_cas" so that a user
# doesn't know which CAs they are prevented from seeing!
#
### auth_private_attributes = ["...", ...]
# Config File auth provider details (mandatory when auth_type = "config-file")
#
# The Config File auth provider allows you to define one or more users which can
# then be used to login to the Krill web UI.
#
# Example:
# auth_type = "config-file"
#
# [auth_users]
# "joe@example.com" = { attributes={ role="admin", exc_cas="ca1" }, password_hash="..." }
#
# Syntax:
# auth_users = { "some id" = { ... } [, "another id" = { ... }, ...] }
#
# Alternative syntax:
# [auth_users]
# "some id" = { ... }
# "another id" = { ... }
#
# Where { ... } can contain the following fields:
#
# Field Mandatory? Notes
# ----------------------------------------------------------------------------
# id Yes Email address or other identifier for the user.
# To be entered in the username form field in the
# web UI when logging in. Also shown in the Krill
# event history as the actor to which the action is
# attributed.
#
# password_hash Yes Generate this value using the 'krillc config user'
# command on the command line. The web UI will hash
# the password entered in the login form and submit
# it to Krill for comparison to this hash, thereby
# ensuring that passwords are neither transmitted
# nor persisted.
#
# attributes No Zero or more key=value pairs, e.g. role="admin".
# The built-in authorization policy (see above)
# requires a role attribute with value "admin",
# "readonly" or "readwrite". Attribute key=value
# pairs may be displayed by the Krill web UI. To
# prevent attributes being sent to the UI, use the
# auth_private_attributes setting (see above).
#
### auth_type = "config-file"
###
### [auth_users]
### ...
# OpenID Connect auth provider details (mandatory when auth_type = "openid-connect")
#
# The OpenID Connect auth provider delegates authentication of users to an
# external provider that implements the OpenID Connect Core 1.0 specification.
# It can also optionally retrieve user attributes (known as "claims" [*1]) from
# the provider, or from an [auth_users] section in the Krill configuration file.
#
# Syntax:
# auth_openidconnect = { issuer_url="...", client_id="...", client_secret="..." }
#
# Alternative syntax:
# [auth_openidconnect]
# issuer_url = "..."
# client_id = "..."
# client_secret = "..."
# insecure = false
# extra_login_scopes = ["...", ...]
# extra_login_params = ["...", ...]
# logout_url = "..."
#
# [auth_openidconnect.claims]
# ...
#
# Where { ... } can contain the following fields:
#
# (Sub)Field Mandatory? Notes
# ----------------------------------------------------------------------------
# issuer_url Yes Provided by your OpenID Connect provider. This is
# the URL of the OpenID Connect provider discovery
# endpoint. "/.well-known/openid_configuration"
# will be appended if not present. Krill will fetch
# the OpenID Connect Discovery 1.0 compliant JSON
# response from this URL when Krill starts up. If
# this URL does not match the "issuer" value in the
# discovery endpoint response or if the discovery
# endpoint cannot be contacted, Krill will fail to
# start.
#
# client_id Yes Provided by your OpenID Connect provider.
#
# client_secret Yes Provided by your OpenID Connect provider.
#
# insecure No Defaults to false. Setting this to true will
# disable verification of the signature of the
# OpenID Connect provider token ID endpoint
# response. Setting this to false may allow attackers
# to modify responses from the provider without
# being detected. Setting this to false is strongly
# discouraged.
#
# extra_login_scopes No Provider specific. Defaults to "". A
# comma-separated list of OAuth 2.0 scopes to be
# passed to the provider when a user is directed to
# login with the provider. Scopes are typically
# used to instruct the provider to send additional
# user details along with provider token responses.
# One common scope is "profile" which often causes
# the server to respond with email addresses and
# other personal details about the user. If the
# OpenID Connect provider discovery endpoint shows
# that "email" is a supported scope then the "email"
# scope will be requested automatically, you don't
# need to specify it here in that case.
#
# extra_login_params No A { key=value, ... } map of additional HTTP query
# parameters to send with the authorization request
# to the provider when redirecting the user to the
# OpenID Connect provider login form. Section
# 3.1.2.1. Authentication Request in the OpenID
# Connect Core 1.0 specification [*2] lists various
# parameters that can be sent but the supported set
# varies by provider. The prompt=login parameter is
# automatically sent by the provider and thus does
# not need to be provided using this setting. Can
# also be specified as a separate TOML table, e.g.:
#
# [openid_connect.extra_login_params]
# display=popup
# ui_locales="fr-CA fr en"
#
# logout_url No A URL to direct the browser to redirect the user
# to in order to logout. Ideally this is not needed
# as the provider OpenID Connect Discovery response
# should contain the details Krill needs, but for
# some providers a logout_url must be specified
# explicitly. If the provider discovery response
# doesn't announce support for any supported
# mechanisms and no logout_url value is set then
# Krill will default to directing the user back to
# the Krill UI index page from where the user will
# be directed to login again via the OpenID Connect
# provider.
#
# claims No A { <claim>={...}, ... } map used to extract and
# +-- source No optionally transform claim values from the OpenID
# +-- jmespath Yes Connect provider responses [*3, *4]. Each claim
# +-- dest No specification results in zero or one additional
# attribute name=value pairs that can be shown
# in the Krill web UI and can be tested by the
# authorization policy.. Can also be specified as
# a separate TOML table, e.g.:
#
# [openid_connect.claims]
# name = { source="...", jmespath="...", dest="..."}
# name2 = { ... }
#
# An "id" claim is required. If not specified the
# following default "id" claim configuration will
# be used:
#
# id = { jmespath="email" }
#
# To prevent attributes being sent to the UI, use
# the auth_private_attributes setting (see above).
#
# source If the 'source' subfield is not provided, all
# available token and userinfo claim responses from
# the OpenID Connect provider will be searched for
# a field that matches the 'jmespath' expression.
#
# If specified the value identifies a specific
# claim set to search and can be one of the
# following values:
#
# config-file
# id-token-standard-claim
# id-token-additional-claim
# user-info-standard-claim
# user-info-additional-claim
#
# The source = "config-file" value is special, it
# doesn't refer to an OpenID Connect provider
# response claim set but rather to user attributes
# looked up using the "id" claim value as a key to
# index into the [auth_users] user attribute map.
#
# The "id" claim value cannot therefore itself be
# taken from [auth_users], and password_hash values
# in [auth_users] are ignored as authentication is
# handled by the OpenID Connect provider.
#
# dest The optional "dest" field can be used to set the
# value of an attribute by a different name than
# the claims key used. This can be used to specify
# multiple claim rules that attempt to extract a
# a value for the same claim. The first matching
# rule in such cases will be used.
#
# jmespath The "jmespath" field specifies a JMESPath [*5]
# expression which is used to find a matching field
# in the OpenID Connect provider JSON response. In
# addition to the standard JMESPath functions the
# Krill implementation includes two custom regular
# expression based functions to match and
# optionally replace parts of the value of the
# fieldm matched by the JMESPath expression. These
# two functions are:
#
# recap(<field name/value>, 'capturing regex')
# resub(<field name/value>, 'search regex', replace'))
#
# With these extra functions cases where part of a
# complex string should be matched, extacted and
# (with resub) mapped to a value that matches what
# the authorization policy expects. E.g. it could
# be used to match a substring and then to "output"
# a particular Krill role name.
#
# If the combination of "resub()" and "dest" is
# not powerful enough you can take value matching
# even further using policy file rules. "dest" and
# "resub" may be combined with policy file rules in
# order to simplify the policy file rules needed.
#
# When determining the right "jmespath" expression
# to use, match failures will be logged at "info"
# level (as the auth policy in use may not require
# all configured claims to be found for all users)
# including a list of claims that are available to
# match. Additionally at "debug" level details
# about the claim search process are logged and at
# "trace" level the OpenID HTTP Connect provider
# HTTP/JSON responses are logged.
#
# Escaping: If you need to use double quotes to
# escape a JMESPath identifier you will need to use
# jmespath='...' or jmespath='''...''' instead of
# jmespath="..." in the Krill configuration file.
# See the JMESPath [*6] and TOML [*7] specs for
# more information about quoting and escaping.
#
# References:
# *1: https://openid.net/specs/openid-connect-core-1_0.html#Claims
# *2: https://openid.net/specs/openid-connect-core-1_0.html#AuthRequest
# *3: https://openid.net/specs/openid-connect-core-1_0.html#TokenResponse
# *4: https://openid.net/specs/openid-connect-core-1_0.html#UserInfoResponse
# *5: https://jmespath.org/
# *6: https://jmespath.org/specification.html#identifiers
# *7: https://toml.io/en/v1.0.0#string
#
# ------------------------------------------------------------------------------
# Registering Krill with an OpenID Connect provider:
# ------------------------------------------------------------------------------
# In order to communicate with an OpenID Connect provider, Krill must first be
# registered with that provider. As a result of registration you will be issued
# a client_id and a client_secret, and possibly also an issuer_url (or you may
# have to consult the provider documentation to determine the issuer_url).
#
# When registering you will usually need to specify a callback URL. For Krill
# this should be <service_uri>auth/callback (replace <service_uri> with the
# actual value set above).
#
# When auth_type = "openid-connect" the client details MUST be provided to Krill
# via settings in the [auth_openidconnect] section of the configuration file.
#
# ------------------------------------------------------------------------------
# Required OpenID Connect provider capabilities:
# ------------------------------------------------------------------------------
#
# The OpenID Connect provider must implement the following specifications:
#
# https://openid.net/specs/openid-connect-core-1_0.html
# https://openid.net/specs/openid-connect-discovery-1_0.html
# https://openid.net/specs/openid-connect-rpinitiated-1_0.html
#
# At the issuer_url endpoint the provider MUST announce support for at least the
# following:
#
# "issuer": ".."
# "authorization_endpoint": "..",
# "token_endpoint": "..", ("userinfo_endpoint" is also supported if available)
# "jkws_uri": "..",
# "scopes_supported": ["openid"]
# "response_types_supported": ["code"]
# "response_modes_supported": ["query"]
# "grant_types_supported": ["authorization_code"]
# "id_token_signing_alg_values_supported": ["RS256"]
# one of: "end_session_endpoint": ".." or "revocation_endpoint": ".."
#
# ------------------------------------------------------------------------------
# A note about HTTPS certificates:
# ------------------------------------------------------------------------------
# If the provider URLS are HTTPS URLs (which they should be unless this
# deployment of Krill is only for testing) then the HTTPS certificate must have
# been issued by a CA in the O/S CA certificate store, i.e. either a well known
# authority that is included in the store by default, or a custom CA that you
# have added to the store yourself. Krill will fail to connect to a provider
# that uses a self-signed certificate or a certificate from an unknown root
# certificate authority. For more information see for example:
# http://manpages.ubuntu.com/manpages/xenial/man8/update-ca-certificates.8.html
# ------------------------------------------------------------------------------
#
# ------------------------------------------------------------------------------
# A note about end_session_endpoint and revocation_endpoint:
# ------------------------------------------------------------------------------
# "end_session_endpoint" is defined by various [*1] OpenID Connect draft
# specifications relating to logout. In Krill it is used for the purpose defined
# in the OpenID Connect RP-Initiated Logout 1.0 spec [*1], namely for Krill as
# the RP (OpenID Connect terms Krill a Relying Party in this context, which is
# particularly confusing given that the term Relying Party also has meaning in
# Krill's native RPKI domain) to be able to initiate logout of the user at the
# provider. Krill also requires that the endpoint either honours the
# "post_logout_redirect_uri" HTTP query parameter (defined as OPTIONAL in the
# spec) or that the provider can be configured with corresponding behaviour,
# i.e. to redirect the end-user user-agent (browser) back to Krill after logout
# is completed at the provider. If support for this is lacking it is undefined
# where the user will end up after logout, which is not an issue if the user
# was finished with Krill, but is annoying if the logout was done in order to
# re-login to Krill as a different user. At least one provider has been observed
# which does NOT support this endpoint.
#
# As an alternative Krill also supports "revocation_endpoint"
# (see https://tools.ietf.org/html/rfc7009 "OAuth 2.0 Token Revocation") which
# is used to terminate the users login session at the provider without leaving
# the Krill web UI.
#
# Finally if neither of these mechanisms are supported a logout_url can be
# specified explicitly via configuration.
#
# References:
# *1: https://openid.net/specs/openid-connect-session-1_0.html
# *2: https://openid.net/specs/openid-connect-rpinitiated-1_0.html
# *3: https://tools.ietf.org/html/rfc7009
#
# ------------------------------------------------------------------------------
# Example RedHat KeyCloak configuration:
# ------------------------------------------------------------------------------
# This example is for a local test deployment of RedHat KeyCloak:
#
# [auth_openidconnect]
# issuer_url = "http://localhost:8082/auth/realms/myrealm"
# client_id = "krill"
# client_secret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
#
# That's it! For this to work you must already have configured your KeyCloak
# instance e.g. with a realm, client (with redirect URI set), users and an
# attribute mapper (to expose a custom user attribute as a "role" claim) and a
# "role" attribute for each user.
#
# ------------------------------------------------------------------------------
# Example Azure Active Directory configuration:
# ------------------------------------------------------------------------------
# This example is for a Microsoft Azure cloud Active Directory instance that
# permits only read-only and read-write access to users that login via the Krill
# web UI:
#
# [auth_openidconnect]
# issuer_url = "https://login.microsoftonline.com/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/v2.0"
# client_id = "yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy"
# client_secret = "zzzzzzzz"
# extra_login_scopes = ["offline_access"]
#
# [auth_openidconnect.claims]
# id = { jmespath="name" }
# ro_role = { jmespath="resub(roles[?@ == 'gggggggg-gggg-gggg-gggg-gggggggggggg'] | [0], '^.+$', 'readonly')", dest="role" }
# rw_role = { jmespath="resub(roles[?@ == 'hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh'] | [0], '^.+$', 'readwrite')", dest="role" }
#
# For this to work you must already have configured in the Azure portal your AD
# tenant, app registration and enterprise application settings (with redirect
# URI), users, group assignments and optional claim configuration (in the above
# example AD was configured to expose groups as roles).
#
# The JMESPath expression matches on Azure AD group GUID values, taking the
# first match it finds and then setting the "role" attribute to either readonly
# or readwrite depending on which GUID was matched. The GUIDs for your groups
# will be different than those used in this example, see your Krill log for the
# GUIDs to match on.
#
# The offline_access scope is required in order to trigger Azure Active
# Directory to issue a refresh token to Krill.
#
# ------------------------------------------------------------------------------
# Example Amazon Web Services Cognito configuration:
# ------------------------------------------------------------------------------
# [auth_openidconnect]
# issuer_url = "https://cognito-idp.eu-central-1.amazonaws.com/eu-central-1_xxxxxxx"
# client_id = "yyyyyyyy"
# client_secret = "zzzzzzzz"
# logout_url = "https://dddddddd.auth.eu-central-1.amazoncognito.com/logout?client_id=yyyyyyyy&logout_uri=https://your.krill.domain/"
#
# [auth_openidconnect.claims]
# role = { jmespath='''resub("cognito:groups"[?@ == 'KrillAdmins'] | [0], '^.+$', 'admin')''' }
#
# For this to work you must already have configured in the AWS Cognito console
# a group called KrillAdmins and have added the logging in user to that group.
# Otherwise the "cognito:groups" claim will not be present in the ID token
# response issued by AWS Cognito. You also need to have set a "Sign Out URL" for
# in your AWS Cognito "App client settings" which should match the value you
# use for the "logout_uri" query parameter in the logout_url Krill setting.
#
# logout_url needs to be set because AWS Cognito doesn't advertise support for
# any of the OpenID Connect logout mechanisms that Krill understands.
#
# dddddddd should be replaced by your AWS Cognito domain prefix that you
# specified in hte AWS Cognito "App integration" -> "Domain name" console
# setting. The regions in the URLs should also match those that you are using.
#
# Note the use of ''' which is needed because the Cognito groups claim contains
# a colon which is a reserved character in JMESPath identifiers.
#
# ------------------------------------------------------------------------------
# Example Google Cloud Platform configuration:
# ------------------------------------------------------------------------------
# [auth_openidconnect]
# issuer_url = "https://accounts.google.com/.well-known/openid-configuration"
# client_id = "xxxxxxxx.apps.googleusercontent.com"
# client_secret = "yyyyyyyy"
# extra_login_scopes = ["profile"]
#
# [auth_openidconnect.claims]
# role = { jmespath='''recap(resub(picture, '^.+photo\.jpg$', 'admin'), '(admin)')''' }
#
# For this to work you must already have created Credentials in the Google
# developer console and have set the redirect URI to your Krill API
# /auth/callback public URL.
#
# In this example we have included the ".well-known/..." part of the issuer_url
# to demonstrate that Krill will accept the URL with or without it.
#
# ''' is used to ensure that characters in the regular expression don't conflict
# with JMESPath reserved characters. The JMESPath expression in this example is
# not a useful real world example as it grants "admin" rights to any Google
# account that has an associated picture whose URL ends in photo.jpg.
#
# The JMESPath expression in this example uses an outer recap() call to sanity
# check that the resulting role value is what we expect it to be. Without this
# a URL that doesn't match would pass straight through resub() unchanged. The
# recap() check is needed because you might use resub() to "clean up" values
# that in some cases don't need any cleaning and thus would still be wanted
# even though not modified.
#
# Also note that, while not visible in the configuration above, the GCP OpenID
# Connect provider advertizes an RFC 7009 OAuth 2.0 Token Revocation compatible
# `revocation_endpoint` which Krill will use to revoke the Google login token
# when the user logs out of Krill.