Client to implemented the User Managed Access (UMA) flow as a
server-side nginx `auth_request` agent.
Explore the docs »
Helm Chart
·
Report Bug
·
Request Feature
Table of Contents
All access attempts to a Resource Server, (e.g. Catalogue, Data Access, ADES, etc.), are subject to the policy enforcement of the PEP (Policy Enforcement Point). For reasons of performance, it is desirable for Nginx to act as the reverse-proxy in this protection flow, rather than the proxy function of the PEP which is not designed for large numbers of concurrent requests or large data volumes.
Through the Module ngx_http_auth_request_module, Nginx provides a mechanism in which its reverse-proxy function can defer the authorization decision to a subrequest, and so offer protected access. Hence, this auth_request
interface offers a means to invoke the services of the PEP, whilst maintaining proxy performance.
The auth_request
approach invokes the subrequest with the expectation to receive one of three possible responses: 2xx (OK)
, 401 (Unauthorized)
, 403 (Forbidden)
. Only 2xx (OK) auth_request
responses will permit the onward proxy of the request. Otherwise the 401/403 response is returned to the client.
In order to inform its decision the PEP is provided with pertinent request information through http headers set by nginx in the subrequest:
X-Original-Method
: http method of client requestX-Original-Uri
: path to the requested resource
The PEP implements the nginx auth_request
interface and so returns 2xx, 401 or 403. In the case of a 401 response, then the PEP expects the client to follow the UMA (User Managed Access) flow, using the 'ticket' that is provided in the Www-Authenticate
header it returns with the 401 response.
A typical client, such as a browser, is not in a position to follow the UMA flow. Thus, the uma-user-agent
performs the role of UMA client on behalf of the end-user client (user agent). The uma-user-agent sits between nginx and the PEP, to intercept the PEP 401 responses (with Www-Authenticate
header) to follow the UMA flow, exchanging a 'ticket' for an RPT (Relying Party Token), which can then be re-presented to the PEP and so gain authorization.
This flow, and the chaining of the uma-user-agent -> PEP in the nginx auth_request
subrequest, is illustrated in the following sequence diagram.
The uma-user-agent implements the nginx auth_request
subrequest, as described here http://nginx.org/en/docs/http/ngx_http_auth_request_module.html.
HTTP Inputs
The uma-user-agent supports the following inputs on the http subrequest from nginx:
- http headers:
X-Original-Method
: http method of client requestX-Original-Uri
: path to the requested resourceAuthorization
: carryingBearer
token for user ID (optional)X-User-Id
: user ID token from OIDC (optional)
- http cookie:
auth_user_id
: user ID token from OIDC (optional)
Cookie name is configurableauth_rpt-<endpoint-name>
: RPT from previous successful access
Cookie name is configurable
User ID Token
Note that there are three means through which the User ID Token (from OIDC) can be presented to the uma-user-agent
.
These are in priority order:
Authorization
header as a bearer token - in the form:Authorization: Bearer <token>
X-User-Id
headerauth_user_id
cookie (name of cookie is configurable)
HTTP Outputs
The uma-user-agent sets the following headers in the http response:
2xx (OK)
X-User-Id
: user ID token, to be passed-on to the target Resource ServerX-Auth-Rpt
: RPT from successful authorizationX-Auth-Rpt-Options
: cookie options for RPT
401 (Unauthorized)
- Www-Authenticate: defines http authorization methods
403 (Forbidden)
No specific headers
Nginx must be configured to 1) invoke the auth_request
subrequest, 2) set the values to be passed in the http subrequest, and 3) to handle any output http headers from the subrequest. For example...
location /resource-server/ {
auth_request /authcheck;
auth_request_set $x_user_id $upstream_http_x_user_id;
auth_request_set $x_auth_rpt $upstream_http_x_auth_rpt;
proxy_set_header X-User-Id $x_user_id;
add_header Set-Cookie $x_auth_rpt;
}
location ^~ /authcheck {
internal;
proxy_pass http://<uma-user-agent-host>/;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
proxy_set_header X-Original-Method $request_method;
}
The uma-user-agent reads its configuration from files in the directory specified by the CONFIG_DIR
environment variable. In the absence of override the default diectory is /app/config/
.
Configuration is read from two files:
client.yaml
Details for the client that is registered with the Authorization Server.config.yaml
General application configuration.
The client.yaml
file supports the following values:
Name | Description | Default |
---|---|---|
client-id | The ID of the client registered in the Authorization Server |
n/a |
client-secret | The Secret of the client registered in the Authorization Server |
n/a |
The config.yaml
file supports the following values:
Name | Description | Default |
---|---|---|
logging.level | Logging level:panic , fatal , error , warn /warning , info , debug , trace |
info |
network.httpTimeout | Timeout for all http client requests (secs) | 10 |
network.listenPort | Listening port for the uma-user-agent service | 80 |
pep.url | URL for the PEP, to daisy-chain the auth_request call |
http://pep |
userIdCookieName | Name of the cookie that carries the User Id Token | auth_user_id |
authRptCookieName | Name of the cookie that carries the RPT of the last successful request Note that this is a prefix for the name that is appended with -<endpoint-name> |
auth_rpt |
authRptCookieMaxAge | Maximum age of the RPT cookie, to set the expiry (secs) | 300 |
unauthorizedResponse | Text that should form the value for the Www-Authenticate header in the 401 response |
n/a |
retries.authorizationAttempt | Number of retry attempts in the case of an unexpected unauthorized response - i.e. the UMA flow has been successfully followed to obtain a fresh RPT, but it is still rejected A zero 0 value means no retries. |
1 |
retries.httpRequest | Number of retry attempts in the case of an http request that fails due to specific conditions: * 5xx status code (i.e. server-side error) * Request timeout (i.e. unresponsive server) A zero 0 value means no retries. |
1 |
openAccess | Boolean to set 'open' access to the resource server. A value of true bypasses protections |
false |
insecureTlsSkipVerify | Boolean that controls whether the uma-user-agent client verifies the server's (e.g. Authorization Server for UMA flows) certificate chain and host name.If insecureTlsSkipVerify is true, then the uma-user-agent accepts any certificate presented by the server and any host name in that certificate.In this mode, TLS is susceptible to machine-in-the-middle attacks, and should only be used for testing. |
false |
The uma-user-agent
is implemented using the Go programming language, with support from the following modules:
- Runtime:
- fsnotify v1.5.4
- gorilla/mux v1.8.0
- logrus v1.9.0
- viper v1.13.0
- Build:
To get a local copy up and running follow these simple example steps.
To run natively, the go runtime is required - it can be installed by downloading from here https://golang.org/dl/.
Alternatively, it can be run locally via docker
and docker-compose
, which can be installed by downloading from:
docker
: https://docs.docker.com/engine/install/docker-compose
: https://docs.docker.com/compose/install/
Clone the repo from GitHub...
git clone https://github.com/EOEPCA/uma-user-agent.git
cd uma-user-agent
Run Natively
To run natively execute the script...
./run.sh
Run Via Docker
To run via docker-compose
execute the script...
/run-docker.sh
Helm Chart (Kubernetes)
A helm chart is available for deployment to Kubernetes, here https://github.com/EOEPCA/helm-charts/tree/main/charts/uma-user-agent.
Ensure helm is installed (see https://helm.sh/docs/intro/install/)...
curl -sfL https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash -s -
Add the eoepca helm chart repo...
helm repo add eoepca https://eoepca.github.io/helm-charts
helm repo update
Deploy a helm release my-uma-agent
to the Kubernetes cluster...
helm install my-uma-agent eoepca/uma-user-agent -f my-values.yaml
This will deploy with default values, plus overrides from the file my-values.yaml
.
Contributions are what make the open source community such an amazing place to learn, inspire, and create. Any contributions you make are greatly appreciated.
If you have a suggestion that would make this better, please fork the repo and create a pull request. You can also simply open an issue with the tag "enhancement". Don't forget to give the project a star! Thanks again!
- Fork the Project
- Create your Feature Branch (
git checkout -b feature/AmazingFeature
) - Commit your Changes (
git commit -m 'Add some AmazingFeature'
) - Push to the Branch (
git push origin feature/AmazingFeature
) - Open a Pull Request
Distributed under the ESA Software Community Licence Permissive. See LICENSE.txt
for more information.
Your Name - @eoepca - eoepca.systemteam@telespazio.com
Project Link: https://github.com/EOEPCA/uma-user-agent
- README.md is based on this template by Othneil Drew.