Auth Policy

Return to Workshop

Authorizing and Authenticating Access via Policy

In the previous labs we secured and verified the service-to-service communication. But what about user-to-service communication (aka origin authentication)? The service mesh can help with that too. To do this, we need to bring in an identity provider that will issue JSON Web Tokens (JWTs) to signed in users. JWTs are an open, industry standard (RFC 7519) way of sharing identity. The app-ui service will pass those JWTs along with it's API requests. This lets the service mesh's sidecar proxies can verify, get role data, and enforce access.

Let's walk through a basic example of restricting service access via Authentication and Authorization policies.

Authenticated Users Only

We can lock down the service entirely and only let authenticated users access it.

Apply a new authentication policy with the following command:
sed "s|microservices-demo|$PROJECT_NAME|" ./istio-configuration/policy-boards-jwt.yaml | oc apply -f -

This specifies the requirements for traffic to the boards service to have a JWT with specific properties. It looks like this:

kind: Policy
  name: boards-jwt
  namespace: microservices-demo
  - name: boards
  - mtls:
      mode: STRICT
  - jwt:
      issuer: ""
      jwksUri: ""
      - excludedPaths:
        - exact: /health_check
        - prefix: /status/
  principalBinding: USE_ORIGIN

We mentioned earlier that JWT shares identity info, the JWKS endpoint gives us keys to verify the data of the JWT is from our trusted source.

Goto your webapp and click the Shared navigation button
Refresh the page a few times and try to add something to the shared board

It will fail with the following error (once it takes effect).

Login as user "demo" with password "demo"
Try to access the page again

You should now see a list of shared items

You might need to refresh the page a few times before it takes effect

At the time on this writing Service Mesh 1.0 is using Istio 1.1.

This section of the lab requires Istio 1.4 or later - which is expected to GA soon.

Please read but do not execute the steps

Only The Cool Kids

In this scenario we want to further secure access to the shared boards list so only a certain group of users can post to it. And we will do this this purely via the Service Mesh configuration. It's pretty straightforward to do.

Apply an authorization policy with the following command:
sed "s|microservices-demo|$PROJECT_NAME|" ./istio-configuration/authorization-boards-shared-lockdown.yaml | oc apply -f -

That configuration looks like this:

kind: AuthorizationPolicy
  name: boards-shared-lockdown
  namespace: microservices-demo
      app: boards
  - from:
    - source:
      principals: ["*"]
    - operation:
      methods: ["POST"]
      paths: ["/shareditems/*"]
      - key:[realm_access.roles]
        values: ["cool-kids"]
  - from:
    - source:
      principals: ["*"]
    - operation:
      methods: ["GET"]
      - key:[scope]
      values: ["openid"]

An authorization policy includes a selector and a list of rules. The selector specifies the target that the policy applies to - in this case our boards microservice. While the rules specify who (from) is allowed to do what (to) under which (when) conditions - in this case any source can POST as long as they have the "cool-kids" role listed in their JWT payload.

So, now that we've applied it, let's try to access your boards service when you're not in the cool kids club.

Goto your webapp and shared page of the website
Try to add something to the shared board

You should be able to see the items, but posting will fail with the following error.

Now login as user "theterminator" with password "illbeback"
Try again to add something to the shared board

Your new item should show in the shared list

Now let's put things back to normal
oc delete authorizationpolicy/boards-shared-lockdown
oc delete policy/policy/boards-jwt

How it Works

Our app-ui microservice requests the JWT from the Keycloak SSO when a user logs in. If logged in, the JWT is always passed (in the request header) from the app-ui to any services it calls. All our services have Envoy sidecar proxies running and are seeing the traffic, including the JWT in app-ui request headers. So the configuration we applied is used to inform sidecar proxies to follow the policies we set. When we weren't logged in there was no JWT to pass along so our call requests failed. Only after we were logged with as a valid user did we pass along a valid JWT. And each user's JWT was different, so the when conditions only matched for theterminator, allowing him able to POST to the shared board.

If you have the time and want to dig deeper, you should read more about configuring Keycloak and about JWTs.

Check out highlevel diagrams of the flows we executed below:

Fail Case

Success Case

Authorization Policy Summary

If you have used RBAC prior to 1.4 of Istio you might have noticed that it's a lot easier now. Here's a blog post outlining the differences:

Workshop Details

Domain Red Hat Logo
Student ID

Return to Workshop