Anthos Service Mesh user authentication is an integrated solution for browser-based end-user authentication and access control to your deployed workloads. It lets you integrate with existing Identity Providers (IDP) for user authentication and uses Istio APIs and authorization policies for access management. It is a user-friendly alternative to Istio JSON Web Token (JWT) authentication.
A typical use-case is when an organization uses Anthos Service Mesh to host a web application for its workforce to access via a web browser. In addition, the organization needs to use their existing identity provider to manage user identities. Anthos Service Mesh user authentication makes it easy for users to authenticate using a standard web-based OpenID Connect (OIDC) login and consent flow. When the user authenticates, Anthos Service Mesh enforces Istio authorization policies, and on successful authorization, it transmits the identity to workloads in a secure credential format.
How it works
Anthos Service Mesh user authentication introduces a new component, authservice
.
This component integrates with the Envoy-based ingress as an external
authorization service that intercepts all the incoming requests for
authentication. authservice
implements the client-side of the OIDC protocol
and enables user access to applications via a browser, where users complete an
interactive authentication and consent flow to establish a short-lived session.
authservice
implements industry standard protocols to integrate
with any identity provider that can act as a OIDC authorization server. When the
user is authenticated, the principal information is encapsulated in an RCToken
in
JWT format, signed by authservice
which it forwards to the Istio
authorization layer in the ingress. This model provides perimeter access control
for traffic into the mesh. If the user is authorized to access a resource, this
RCToken is also forwarded to the microservices to obtain principal information
and enforce fine-grained access control.
The following diagram shows the location of authservice
in the mesh and how
it relates to the other parts of the mesh, such as the ingress, workloads,
user's browser, and any existing IDP.
Administrators can install authservice
as an add-on over an Anthos Service Mesh
installation. When installed, authservice
reads the OIDC endpoint
configuration and other associated settings defined in the UserAuth
custom
resource. The administrator can use Anthos Service Mesh ExternalAuthorization
APIs
to configure auth_server
as a filter on the ingress.
Install the user authentication service
The following steps explain how to configure the authservice
.
Prerequisites
Ensure that you meet the prerequisites by using the following steps.
Customize the installation using the user authentication overlay
To install the user authentication service, you must customize the ASM installation to add a mesh level external authorization provider.
Get the example user auth overlay and update it if there are any customizations in your mesh. It is a recommended best practice to maintain this overlay file in your source control.
curl https://raw.githubusercontent.com/GoogleCloudPlatform/asm-user-auth/release-0.1/overlay/user-auth-overlay.yaml > user-auth-overlay.yaml
Follow the install ASM with overlay to use a Google-provided script to install Anthos Service Mesh with the user authentication overlay. For example:
/install_asm \ --project_id "PROJECT_ID" \ --cluster_name "CLUSTER_NAME" \ --cluster_location "CLUSTER_LOCATION" \ --mode install \ --enable_all \ --custom_overlay user-auth-overlay.yaml
The user authentication
kpt
packages creates anAuthorizationPolicy
to reference the external authorization provider specified bypkg/ext-authz.yaml
.
Prepare the OIDC client configuration
Set your OIDC client configuration by using the following steps. This guide uses Google as an IDP, but you can use any IDP that supports OIDC authentication.
In the Google Cloud console, go to API & Services > Credentials.
Go to Create Credentials, then choose OAuth client ID. If required, set your OAuth consent screen options, then configure the following options:
- Set Application type to Web application.
- Set Authorized redirect URI to
https://localhost:8443/_gcp_anthos_callback
.
Then, click Save.
In addition, save your client ID and client secret to use later:
export OIDC_CLIENT_ID='<your-client-id>' export OIDC_CLIENT_SECRET='<your-client-secret>' export OIDC_ISSUER_URI='https://accounts.google.com'
Get the kpt
packages
Use the following steps to install the recommended authservice
configuration
from the public repository.
These commands retrieve the latest authservice
container and start it as
a Pod in the asm-user-auth
namespace. It also configures the ingress
to intercept all requests.
Get the kpt package:
kpt pkg get https://github.com/GoogleCloudPlatform/asm-user-auth@release-0.1 . cd asm-user-auth/
Set the redirection URL and secret for ingress gateway
OAuth2
requires a redirection URL hosted on an HTTPS-protected endpoint. These
commands are for example purposes and simplify setup by generating a self-signed
certificate for the Istio ingress gateway. A production deployment should
not use self-signed certificates.
Generate a self-signed certificate:
openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem \ -days 365 -nodes -subj '/CN=localhost'
Create a secret for the ingress gateway to host HTTPS traffic:
kubectl create -n istio-system secret tls userauth-tls-cert --key=key.pem \ --cert=cert.pem
Apply the encryption and signing keys
The authservice
needs two sets of keys to operate successfully. The first is a
symmetric key for encryption and decryption. This key is used for encrypting the
session state before setting that as a cookie.
The second set of keys are a public/private key pair. This key is used to sign the authenticated user information in JWT format as an RCToken. The public key from this pair is published at a predefined endpoint that the sidecars can use to validate the JWT.
The user authentication kpt
package contains two sample keys for quick setup.
However, you can use your preferred key management system to generate the these keys
instead.
After you generate your keys, put the key data in the same format:
cat ./samples/rctoken_signing_key.json { "keys":[ { "kty":"RSA", "kid":"rsa-signing-key", "K":"YOUR_KEY", # k contains a Base64 encoded PEM format RSA signing key. "useAfter": 1612813735, # unix timestamp } ] }
cat ./samples/cookie_encryption_key.json { "keys":[ { "kty":"oct", "kid":"key-0", "K":"YOUR_KEY", "useAfter": 1612813735 } ] }
Create the kubernetes secret, which
authservice
will mount into its own file system.kubectl create namespace asm-user-auth kubectl label namespace asm-user-auth istio-injection=enabled istio.io/rev=default --overwrite kubectl create secret generic secret-key \ --from-file="session_cookie.key"="./samples/cookie_encryption_key.json" \ --from-file="rctoken.key"="./samples/rctoken_signing_key.json" \ --namespace=asm-user-auth
Deploy the user authentication service
The following commands create the user authentication service and deployment in
the asm-user-auth
namespace.
Set the
oauth
variables:kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientID ${OIDC_CLIENT_ID} kpt cfg set pkg anthos.servicemesh.user-auth.oidc.clientSecret ${OIDC_CLIENT_SECRET} kpt cfg set pkg anthos.servicemesh.user-auth.oidc.issuerURI ${OIDC_ISSUER_URI}
Apply the
kpt
package:kubectl apply -f ./pkg/asm_user_auth_config_v1alpha1.yaml kubectl apply -f ./pkg
The authservice
consumes the UserAuthConfig
CRD to provide end user
authentication. UserAuthConfig
is configurable in the run time, and you can
update it to change the authservice
behavior and configure it with endpoints
for any OIDC authorization server. It contains these fields:
cat pkg/user_auth_config.yaml
apiVersion: security.anthos.io/v1alpha1
kind: UserAuthConfig
metadata:
name: auth-config
namespace: user-auth
spec:
authentication:
- oidc:
clientID: "${OIDC_CLIENT_ID}"
clientSecret: "${OIDC_CLIENT_SECRET}"
issuerURI: "${OIDC_ISSUER_URI}"
redirectURIHost: ""
redirectURIPath: "/_gcp_anthos_callback"
outputJWTAudience: "test_audience"
See user authentication configuration details
for detailed descriptions of the user_auth_config.yaml
fields.
Perform post-install tasks
The following tasks are required after you finish the previous installation steps.
Enable user authentication for your applications
This section demonstrates how to enable user authentication, by using the Online Boutique sample application as an example.
Anthos Service Mesh user authentication uses a
CUSTOM
typed authorization policy to trigger the OIDC flow.
The installation process also creates an Istio gateway to serve HTTPS
traffic using the TLS certificate userauth-tls-cert
you created above.
Here is the pkg/gateway.yaml
configuration.
apiVersion: networking.istio.io/v1beta1
kind: Gateway
metadata:
name: userauth
namespace: asm-user-auth
spec:
selector:
istio: ingressgateway
servers:
- hosts:
- '*'
port:
name: https
number: 443
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: userauth-tls-cert
---
# This ensures the OIDC endpoint has at least some route defined.
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
name: userauth-oidc
namespace: asm-user-auth
spec:
gateways:
- userauth
hosts:
- '*'
http:
- match:
- uri:
prefix: /status
- uri:
prefix: /_gcp_anthos_callback
name: user-auth-route
route:
- destination:
host: authservice
port:
number: 10004
Update the Online Boutique application to use this gateway to serve HTTPS traffic, and use port forwarding to access the application locally:
kubectl apply -f./samples/boutique-route.yaml -n demo kubectl port-forward service/istio-ingressgateway 8443:443 -n istio-system
The ingress gateway on port 8443 will be forwarded to
localhost
to make the application accessible locally.Verify that the Online Boutique sample application is accessible at
https://localhost:8443/
.
Verify user authentication
The Online Boutique application services now require the end user to login via their Google accounts.
Verify that you see the OIDC login page by visiting
https://localhost:8443/
.After you login, click Next and verify that it redirects you to the Online Boutique home page.
Configure authorization policies
After you finish the configuration in the previous steps, each user will be
redirected through a web-based authentication flow. When the flow completes, the
authservice
will generate an RCToken
in JWT format, which it uses to
transmit the authenticated user information.
Add Istio authorization policies at the ingress to ensure that an authorization check occurs for each authenticated user:
kubectl apply -f ./samples/rctoken-authz.yaml
The
rctoken-authz.yaml
file configures the ingress gateway to validate the RC token issued by authservice, and only authorize when the JWT contains the desired fields, such as audiences and issuers.See the following example authorization policy:
apiVersion: security.istio.io/v1beta1 kind: RequestAuthentication metadata: name: require-rc-token namespace: istio-system spec: selector: matchLabels: istio: ingressgateway jwtRules: - issuer: "authservice.asm-user-auth.svc.cluster.local" audiences: - "test_audience" jwksUri: "http://authservice.asm-user-auth.svc.cluster.local:10004/_gcp_user_auth/jwks" fromHeaders: - name: X-ASM-RCTOKEN forwardOriginalToken: true --- apiVersion: security.istio.io/v1beta1 kind: AuthorizationPolicy metadata: name: require-rc-token namespace: istio-system spec: selector: matchLabels: istio: ingressgateway action: ALLOW rules: - when: - key: request.auth.claims[iss] values: - authservice.asm-user-auth.svc.cluster.local - key: request.auth.claims[aud] values: - test_audience
Configure environment-specific settings
The previous steps use localhost
and a self-signed HTTPS certificate for quick
setup. For real production use, use your own domain, such as example.com
.
In addition, ensure the tokenEndpoint
and authorizationEndpoint
configured
in the UserAuthConfig
CRD has a route configured in VirtualService
. The
previous installation steps set this in asm-user-auth/userauth-oidc
VirtualService
.
Manage and rotate keys
There are two sets of keys used by authservice
. You can rotate each key
independently. However, before you rotate the keys, it is important to
understand how the rotation works.
Both keys are in JSON format. The useAfter
field specifies the timestamp since
when the key will be considered to use. During a key rotation, you should
include both old and new keys in the JSON. For example, in the following
example, new-key
will only be used after timestamp 1712813735
.
{
"keys":[
{
"kty":"RSA",
"kid":"old-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1612813735, # unix timestamp
}
{
"kty":"RSA",
"kid":"new-key",
"K":"...", # k contains a Base64 encoded PEM format RSA signing key.
"useAfter": 1712813735, # unix timestamp
}
]
}
Anthos Service Mesh uses the symmetric key for encrypting session data that is stored in
browser cookies. To ensure validity of existing sessions, authservice
attempts
decryption with all keys in the key set. On rotation, the authservice
will use the new key for encrypting new sessions, and will continue to
attempt decryption with the old keys.
The public/private key pair is used to sign RCToken
. The public key is
transmitted to the sidecars by istiod
for JWT verification. It is crucial for
sidecars to receive the new public key before authservice
starts using the new
private key to sign the RCToken
. To that end, authservice
starts publishing the
public key immediately after the key is added, but waits a significant amount of
time before starting to use that to sign RCToken
.
To summarize, when performing key rotations we recommend:
- Perform regular key rotations or on demand as you need.
- In the JSON format, include both the current and the new keys. The new keys should be associated with a timestamp in the future. We recommend that you specify a timestamp at least a couple of hours ahead of the current time.
- Monitor and confirm that the services are still healthy after the new key is in use. Wait at least one day after the new key is being used before moving to next step.
- Remove the old keys from the JSON entries. They are no longer needed.
User authentication configuration details
The following table describes each field in the CRD:
Field name | Description |
---|---|
authentication.oidc |
This section holds the OIDC endpoint configuration and the parameters used in OIDC flow. |
authentication.oidc.certificateAuthorityData |
This is the SSL certificate of the domain of the OIDC authorization server. |
authentication.oidc.clientID |
The OAuth client ID to use for the OIDC authentication flow. |
authentication.oidc.clientSecret |
The OAuth client secret to use for the OIDC authentication flow. |
authentication.oidc.issuerURI |
The URI to use as the issuer in the output RCToken. |
authentication.oidc.redirectURIHost |
The host to be used for OAuth termination URI. If you leave this empty, the host from the
target URL will be used and the redirect URI will be assembled dynamically. This value can be used when a user auth SSO session is desired at a higher level domain. For example, to enable SSO between profile.example.com/ and admin.example.com/, this value can be set to example.com. It will enable a user auth session to be established at example.com that'll be shared amongst all subdomains. Note: If multiple domains are served from the same mesh, example1.com and example2.com, the feature cannot be used, and is recommended to be left empty. |
authentication.oidc.redirectURIPath |
The endpoint path where `authservice` will terminate the OAuth flow. You
should register this URI path plus the host as an authorized redirect URI in the
authorization server for the authentication.oidc.clientID .In addition, this URI should be served from the same service mesh and ingress where `authservice` is enabled. |
authentication.oidc.scopes |
The OAuth scope that should be requested in the authentication request. |
authentication.oidc.groupsClaim |
If the `idtoken` contains a groups claim, use this field to indicate its name. If specified, the service will pass on the data in this claim into the `groups` claim in the output RCToken. |
authentication.outputJWTAudience |
The audience of the RCToken generated by `authservice`. The sidecars can validate the incoming RCToken against this audience value. |
Multi Cluster Deployment
Anthos Service Mesh User Auth supports multi cluster deployment. You need to deploy user auth in each cluster as described above. The user auth configuration such as UserAuth custom resource, OIDC client secret, encryption keys, all need to be replicated in each clusters.
By default ingress gateway will load balance the authentication requests
to any one of authservice
instances. You can use destination rule to configure
the ingress gateway to send requests to the authservice
in the same cluster,
and only fail over to other clusters' authservice
.
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: authservice-fail-over
namespace: asm-user-auth
spec:
host: authservice.asm-user-auth.svc.cluster.local
trafficPolicy:
loadBalancer:
localityLbSetting:
enabled: true
failover:
- from: us-east
to: us-west
- from: us-west
to: us-east
Same as other configuration, this needs to be configured in each cluster.
FAQs
How do I upgrade Anthos Service Mesh with User Auth enabled?
Follow the Anthos Service Mesh upgrade process and specify the
user-auth.yaml
overlay file on the command line toinstall_asm
.