Skip to content

Resource Protection (Gluu)⚓︎

EOEPCA defines Building Blocks within a micro-service architecture. The services are subject to protection within an Identity and Access Management (IAM) approach that includes:

  • Login Service (Authorization Server)
  • Policy Decision Point (PDP)
  • Policy Enforcement Point (PEP)

Building Blocks that act as a Resource Server are individually protected by a Policy Enforcement Point (PEP). The PEP enforces the authorization decision in collaboration with the Login Service and Policy Decision Point (PDP).

The PEP expects to interface to a client (user agent, e.g. browser) using User Managed Access (UMA) flows. It is not typical for a client to support UMA flows, and so the PEP can be deployed with a companion UMA User Agent component that interfaces between the client and the PEP, and performs the UMA Flow on behalf of the client.

The Resource Guard is a ‘convenience’ component that deploys the PEP & UMA User Agent as a cooperating pair.

The Resource Guard ‘inserts itself’ into the request path of the target Resource Server using the auth_request facility offered by Nginx. Thus, the Resource Guard deploys with an Ingress specification that:

  • Configures the auth_request module to defer access authorization to the uma-user-agent service
  • Configures the ingress rules (host/path) for the target Resource Server

Helm Chart⚓︎

The Resource Guard is deployed via the resource-guard helm chart from the EOEPCA Helm Chart Repository.

The chart is configured via values that are fully documented in the README for the resource-guard chart.

It is expected to deploy multiple instances of the Resource Guard chart, one for each Resource Server to be protected.

helm install --version 1.3.1 --values myservice-guard-values.yaml \
  --repo https://eoepca.github.io/helm-charts \
  myservice-guard resource-guard

Values⚓︎

The helm chart is deployed with values that are passed through to the subcharts for the pep-engine and uma-user-agent. Typical values to be specified include:

  • Host/domain details for the Login Service and PDP, e.g. auth.192-168-49-2.nip.io
  • IP Address of the public facing reverse proxy (Nginx Ingress Controller), e.g. 192.168.49.2
  • Name of Persistent Volume Claim for pep-engine persistence, e.g. myservice-pep-pvc
  • TLS Certificate Provider, e.g. letsencrypt-production
  • Optional specification of default resources with which to initialise the policy database for the component
  • Ingress rules definition for reverse-proxy to the target Resource Server
  • Name of Secret that contains the client credentials used by the uma-user-agent to interface with the Login Service.
    See section Client Secret below

Example myservice-guard-values.yaml

#---------------------------------------------------------------------------
# Global values
#---------------------------------------------------------------------------
global:
  context: myservice
  domain: 192-168-49-2.nip.io
  nginxIp: 192.168.49.2
  certManager:
    clusterIssuer: letsencrypt-production
#---------------------------------------------------------------------------
# PEP values
#---------------------------------------------------------------------------
pep-engine:
  configMap:
    asHostname: auth
    pdpHostname: auth
  customDefaultResources:
  - name: "Eric's space"
    description: "Protected Access for eric to his space in myservice"
    resource_uri: "/ericspace"
    scopes: []
    default_owner: "d3688daa-385d-45b0-8e04-2062e3e2cd86"
  volumeClaim:
    name: myservice-pep-pvc
    create: false
#---------------------------------------------------------------------------
# UMA User Agent values
#---------------------------------------------------------------------------
uma-user-agent:
  nginxIntegration:
    enabled: true
    hosts:
      - host: myservice
        paths:
          - path: /(.*)
            service:
              name: myservice
              port: 80
          - path: /(doc.*)
            service:
              name: myservice-docs
              port: 80
    annotations:
      nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
      nginx.ingress.kubernetes.io/enable-cors: "true"
      nginx.ingress.kubernetes.io/rewrite-target: /$1
  client:
    credentialsSecretName: "myservice-agent"
  logging:
    level: "debug"
  unauthorizedResponse: 'Bearer realm="https://portal.192-168-49-2.nip.io/oidc/authenticate/"'
#---------------------------------------------------------------------------
# END values
#---------------------------------------------------------------------------

Client Credentials⚓︎

The uma-user-agent requires Client Credentials for its interactions with the login-service. The uma-user-agent expects to read these credentials from the file client.yaml, in the form…

client-id: <my-client-id>
client-secret: <my-secret>

Client Registration⚓︎

To obtain the Client Credentials required by the uma-user-agent it is necessary to register a client with the login-service, or use the credentials for an existing client.

A helper script is provided to register a basic client and obtain the required credentials. The script is available in the deployment-guide repository, and can be obtained as follows…

git clone -b eoepca-v1.4 git@github.com:EOEPCA/deployment-guide
cd deployment-guide

The register-client helper script requires some command-line arguments…

Usage:
  register_client <authorization-server-hostname> <client-name> [<redirect-uri> [<logout-uri>]]

For example…

./deploy/bin/register-client auth.192-168-49-2.nip.io myclient

INFO: Preparing docker image... [done]
Client successfully registered.
Make a note of the credentials:
client-id: a98ba66e-e876-46e1-8619-5e130a38d1a4
client-secret: 73914cfc-c7dd-4b54-8807-ce17c3645558

Or to register OIDC redirect URLs…

./deploy/bin/register-client auth.192-168-49-2.nip.io myclient https://portal.192-168-49-2.nip.io/oidc/callback/ https://portal.192-168-49-2.nip.io/logout

The script writes the ‘client credentials’ to stdout - in the expected YAML configuration file format - which can be redirected to file…

./deploy/bin/register-client auth.192-168-49-2.nip.io myclient | tee client.yaml
…writes the client credentials to the file client.yaml.

NOTE that the register-client helper relies upon docker to build and run the script.

Client Secret⚓︎

The client.yaml configuration file is made available via a Kubernetes Secret…

kubectl -n myservice-ns create secret generic myservice-agent \
  --from-file=client.yaml \
  --dry-run=client -o yaml \
  > myservice-agent-secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: myservice-agent
  namespace: myservice-ns
data:
  client.yaml: Y2xpZW50LWlkOiBhOThiYTY2ZS1lODc2LTQ2ZTEtODYxOS01ZTEzMGEzOGQxYTQKY2xpZW50LXNlY3JldDogNzM5MTRjZmMtYzdkZC00YjU0LTg4MDctY2UxN2MzNjQ1NTU4

The resource-guard deployment is configured with the name of the Secret through the helm chart value client.credentialsSecretName.

User ID Token⚓︎

As described in the README for the Resource Guard, it is necessary for a request to a protected resource to provide the User ID Token in the request header.

Obtaining the User ID Token⚓︎

In the simple case of a user with username/password held within the Login Service, the User ID Token can be obtained as follows:

curl --location --request POST 'https://auth.192-168-49-2.nip.io/oxauth/restv1/token' \
--header 'Cache-Control: no-cache' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'scope=openid user_name is_operator' \
--data-urlencode 'grant_type=password' \
--data-urlencode 'username=<username>' \
--data-urlencode 'password=<password>' \
--data-urlencode 'client_id=<client-id>' \
--data-urlencode 'client_secret=<client-password>'

The User ID Token is included in the id_token field of the json response.

Alternatively, OAuth/OIDC flows can be followed to authenticate via external identity providers.

User ID Token in HTTP requests⚓︎

The Resource Guard protection supports presentation of the User ID Token via the following HTTP request headers (in order of priority)…

  • Authorization header as a bearer token - in the form: Authorization: Bearer <token>
  • X-User-Id header
  • Cookie: auth_user_id=<token>

    Note that the name of the cookie is configurable

Additional Information⚓︎

Additional information regarding the Resource Guard can be found at: