PingAccess

PAAP agent request

After intercepting a client request, the agent makes an agent request to PingAccess to determine the authorization status of the client request. PingAccess then returns an agent response that either asks the agent to submit a second request with more information or tells the agent how to proceed.

Agent request structure

The agent request effectively mirrors the client request, containing an identical Request-Line and forwarding all headers as they appear in the client request (unless otherwise specified).

One notable exception is that the agent request omits the message-body to improve efficiency because PingAccess usually doesn’t require the message-body to make a policy decision.

If PingAccess needs the message-body, it returns an HTTP 477 response to the agent, as defined in PAAP agent response.

HTTP request headers

The following HTTP request headers might require additional agent processing.

Header details
Content-Length

The Content-Length header in the agent request has a value matching the message-body of the client request.

For the initial agent request, the Content-Length is 0 because the agent omits the message-body, as described in Agent request structure previously.

A follow-up agent request (prompted by a 477 response from PingAccess) would send a Content-Lengthheader indicating the size of the entity-body of the request. The entity-body in the agent request is the same as it is in the client request.

vnd-pi-agent

This optional header lets the agent communicate details about its configuration for Agent inventory logging. The value of the vnd-pi-agent header is a map of comma-separated key-value pairs. The agent might specify the custom keys from its deployment, or use one or more of the following well-known keys:

  • v: The version of the agent making the request.

  • t: The type of agent and the type of platform where the agent resides.

  • h: The hostname of the server where the agent resides.

Syntax for the vnd-pi-agent value conforms to a dictionary in RFC 8941, constraining member-values as an sh-string item. The following three headers are considered semantically equivalent:

vnd-pi-agent: v="1.0.0", h="apache.example.com", t="Apache 2.4.41"
vnd-pi-agent: v="1.0.0", h="apache.example.com"
vnd-pi-agent: t="Apache 2.4.41"
vnd-pi-agent: v="1.0.0"
vnd-pi-agent: h="apache.example.com"
vnd-pi-agent: t="Apache 2.4.41"
vnd-pi-expect

This header allows the agent to tell PingAccess that it has sent all available information about the client request. !477 is the only defined value.

The expect header defined in RFC 2616 could convey the same information with an expectation-extension. However, Ping Identity chose not to use the expect header because language in the RFC suggests that intermediaries might, should, or must reject a request using an expectation-extension they don’t understand with a 417 error.

A simple and effective approach for an agent implementation is to send the initial agent request with a content-length of 0, and without the body and vnd-pi-expect header.

The vnd-pi-expect: !477 header is sent only when an agent receives a 477 response to its initial request. In other words, the initial agent request never has a vnd-pi-expect header, while a follow-up agent request (made in response to an HTTP 477 response) always has !477 as the value for the vnd-pi-expect header.

PingAccess should never respond with a 477 to:

  • An agent request that has !477 as the value of the vnd-pi-expect request header.

  • A GET request.

vnd-pi-v

Indicates the PAAP version the agent is using. The value is 1.0.

vnd-pi-authz

This header is similar to the Authorization header defined in RFC 2616 but is specifically intended to enable an agent to authenticate itself to PingAccess. The syntax for the credentials value of the header is the same as defined in section 2.1 of RFC 6750.

The following example demonstrates what this header looks like:

vnd-pi-authz: Bearer <token> (1)
1 <token> is a secret shared between PingAccess and the PingAccess agent.

In some cases, unrestricted access to the agent protocol might create an information leakage vulnerability. The custom headers in the agent response, for example, could reveal internal details of applications or infrastructure that must be protected. Potentially worse, the values might reveal content from encrypted web access management tokens or reference access tokens. Authenticating agents to PingAccess is one way to mitigate this concern.

PingAccess decides whether authentication is required. Authentication is intended as a static deployment option, and no challenge response constructs are defined.

Failed authentication because of missing or invalid credentials indicates either a configuration problem or unauthorized access attempt. In such circumstances, PingAccess sends a 403 response that should include the vnd-pi-authz header using a quoted string value with human-readable information. This is meant to ease troubleshooting and allow for differentiation from an unauthorized end-user. An agent might then send a 403 or 500 response to the client, depending on which is most appropriate.

vnd-pi-resource-cache

Indicates that the agent response should return the vnd-pi-resource-cache and vnd-pi-resource-cache-ttl headers for the given host. You can find more information about these headers in agent response.

An agent generally includes this header when first establishing its resource definition cache for a particular host, or when its current cache is stale or invalid.

If the agent response omits the necessary headers, the agent can use the literal value requested to request the resource cache data. For example:

vnd-pi-resource-cache: requested
X-Forwarded-For

The X-Forwarded-For header contains the originating IP address of a client making a request. If the X-Forwarded-For header:

  • Isn’t present in the client request, the agent adds it to the agent request with a value indicating the IP address of the client making the connection.

  • Is present in the client request, the agent adds the client’s IP address at the end of the delimited IP address list that this header contains when sent in the agent request.

Host and X-Forwarded-Host

The agent sets the Host header as it appears in the client request, unless the agent can’t manipulate the Host header easily or the X-Forwarded-Host header is already present in the client request. For both of these exceptions, the X-Forwarded-Host header contains the original host requested by the client.

X-Forwarded-Proto

If the X-Forwarded-Proto header is present in the client request, it’s sent unchanged in the agent request. Otherwise, if the scheme (HTTPS or HTTP) differs between the client and agent requests, set the agent request’s X-Forwarded-Proto header to the client request’s scheme.

You can omit this header if the client and agent requests use the same scheme.

PingAccess determines the requested resource and constructs self-referential URIs using the contents of the agent request, including the headers listed previously. PingAccess:

  • Determines the scheme from the client’s connection and the X-Forwarded-Proto header, with the latter taking precedence when present.

  • Determines the host and port from the Host and X-Forwarded-Host headers, with the latter taking precedence when present.

Example requests

Review example requests that use the HTTP headers described in the previous section.

Policy decision request

The following example demonstrates a policy decision request for an unauthenticated user:

GET /application/headers HTTP/1.1
Host: http://example.com/
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: nonce=6424266c-ca9b-4e1f-9fde-d1860bfa2582
vnd-pi-v: 1.0
X-Forwarded-For: 172.30.3.248
vnd-pi-resource-cache: requested
X-Forwarded-Proto: http
vnd-pi-authz: Bearer Agent:htZ2W39EfAPLQd8w9cRT6y

Agent request without POST body

The following example demonstrates an agent request with the POST body omitted. Specifically, the OpenID Connect (OIDC) callback in a web session POST login type.

POST /pa/oidc/cb HTTP/1.1
Host: http://example.com/
Connection: keep-alive
Content-Length: 0
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Origin: https://rhel-test.englab.corp.pingidentity.com:9031
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: nonce=b000c6a2-4a03-4bde-be29-956456cd1d2a
vnd-pi-v: 1.0
X-Forwarded-For: 172.30.3.248
vnd-pi-resource-cache: requested
X-Forwarded-Proto: http
vnd-pi-authz:Bearer Agent:htZ2W39EfAPLQd8w9cRT6y

Agent request with POST body

The following example demonstrates an agent request with the POST body included:

POST /pa/oidc/cb HTTP/1.1
Host: http://example.com/
Connection: keep-alive
Content-Length: 1557
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
Origin: https://rhel-test.englab.corp.pingidentity.com:9031
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Content-Type: application/x-www-form-urlencoded
Accept-Encoding: gzip,deflate
Accept-Language: en-US,en;q=0.8
Cookie: nonce=b000c6a2-4a03-4bde-be29-956456cd1d2a
vnd-pi-v: 1.0
X-Forwarded-For: 172.30.3.248
vnd-pi-resource-cache: requested
X-Forwarded-Proto: http
vnd-pi-expect: !477 (1)
vnd-pi-authz: Bearer Agent:htZ2W39EfAPLQd8w9cRT6y
1 The vnd-pi-expect: !477 header disallows the HTTP 477 agent response to request the message-body because it’s already included.

Authenticated user request

The following example demonstrates a request for an authenticated user trying to access a resource:

GET /application/headers HTTP/1.1
Host: http://example.com/
Connection: keep-alive
Cache-Control: max-age=0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2062.120 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: PA.post=eyJraWQiOiJhcCIsImFsZyI6IkVTMjU2In0.eyJ6b25laW5mbyI6IkFtZXJpY2FcL05ld19Zb3JrIiwic3ViIjoiam9lIiwicGhvbmVfbnVtYmVyIjoiKzEgKDQyNSkgNTU1LTEyMTIiLCJlbWFpbF92ZXJpZmllZCI6InRydWUiLCJsb2NhbGUiOiJlbl9VUyIsInByZWZlcnJlZF91c2VybmFtZSI6Im1nc2FtcGxlIiwiZ2l2ZW5fbmFtZSI6Ik1lcmlkaXRoIiwidXBkYXRlZF90aW1lIjoiMjAxMS0wMS0wM1QyMzo1ODo0MiswMDAwIiwiaWF0IjoxNDEwOTk1NDM2LCJuYW1lIjoiTWVyaWRpdGggR29vZCBTYW1wbGUiLCJiaXJ0aGRhdGUiOiIxOTc3LTEyLTMxIiwiZmFtaWx5X25hbWUiOiJTYW1wbGUiLCJnZW5kZXIiOiJmZW1hbGUiLCJwcm9maWxlIjoiaHR0cHM6XC9cL3d3dy5waW5naWRlbnRpdHkuY29tXC9wcm9kdWN0c1wvcGluZ2ZlZGVyYXRlXC8iLCJ3ZWJzaXRlIjoiaHR0cHM6XC9cL3d3dy5waW5naWRlbnRpdHkuY29tXC8iLCJuaWNrbmFtZSI6Ik1lcmkiLCJtaWRkbGVfbmFtZSI6Ikdvb2QiLCJpc3MiOiJQaW5nQWNjZXNzIiwicGljdHVyZSI6Imh0dHBzOlwvXC93d3cucGluZ2lkZW50aXR5LmNvbVwvaW1hZ2VzXC9waW5nLWxvZ28ucG5nIiwiZXhwIjoxNDEwOTk5MDM2LCJwaS5zcmkiOiIyRUpVREtlTk5HZlNEdzdITWkzeEYzYlBSMlUiLCJlbWFpbCI6ImF1c2VyQGV4YW1wbGUuY29tIiwiYWRkcmVzcyI6eyJyZWdpb24iOiJNRSIsImZvcm1hdHRlZCI6IjEyMyBNYWluIFN0cmVldCwgU21hbGx2aWxsZSwgTUUgIFVTQSAxMTIyMyIsInBvc3RhbF9jb2RlIjoiMTEyMjMiLCJsb2NhbGl0eSI6IlNtYWxsdmlsbGUiLCJzdHJlZXRfYWRkcmVzcyI6IjEyMyBNYWluIFN0cmVldCIsImNvdW50cnkiOiJVU0EifSwiYXVkIjoicG9zdCIsImp0aSI6IjY2NjVkYzllLTUxMWMtNDE0Ni05YWFhLTI0ODUzNTA5NTE4MSIsImdyb3VwIjoic2FsZXMifQ.VRsuSs0LBnlHoJ2k-j0BDdLoGeVdqWD35n9ZxFhphEHFe7tfQ6onKAjRdXLR5rtwPBkJHkLaTLD8Yqcsf0izVw
vnd-pi-v: 1.0
X-Forwarded-For: 172.30.3.248
vnd-pi-resource-cache: requested
X-Forwarded-Proto: http
vnd-pi-authz: Bearer Agent:htZ2W39EfAPLQd8w9cRT6y