I have another use case where I need to send an au...
# talk-oathkeeper
w
I have another use case where I need to send an authz request to a legacy system. Unfortunately, this legacy system is set up in such a way that all web handlers are publicly accessible; this includes the handler I am creating modifying for this authz request. In my fork, I've added a config option to
remote
, and
remote_json
(to start). The config option I've named:
signed_payload
and would include an enhancement to the config schema along these lines:
Copy code
"signed_payload": {
  "title": "Sign payload and set the signature to a named header",
  "default": null,
  "properties": {
    "header": {
      "title": "Header to contain the payload signature (base64)",
      "type": "string",
      "description": "The name of the request header that will be populated with the signature of the payload that will be sent to the authorizer",
      "examples": ["X-Request-Signature", "X-Jwks-Signature"]
    },
    "shared_key": {
      "title": "Shared key to use to sign the payload. (Cannot be set along with 'jwks_url')",
      "type": "string",
      "description": "The shared key to use to sign the payload to generate an HMAC signature of the payload",
      "examples": ["47ac7a07-b504-458d-a081-c80da1cfe6cd"]
    },
    "jwks_url": {
      "type": "string",
      "format": "uri",
      "title": "JSON Web Key URL (Cannot be set along with 'shared_key')",
      "description": "Sets the URL where keys should be fetched from. Supports remote locations (http, https) as well as local filesystem paths.\n.",
      "examples": [
        "<https://fetch-keys/from/this/location.json>",
        "file:///from/this/absolute/location.json",
        "file://../from/this/relative/location.json"
      ]
    }
  }
}
Initially, my thought is to support shared-key (HMAC256) and jwks (RS256, etc) signing. The default headers for each of these would be
X-Request-Signature
and
X-Jwks-Signature
respectively with jwks signing including an additional header matching the
X-Jwks-Signature
(or user-specified header) with
-Kid
appended which would represent the keyId used from the key set (jwks). Internally to support jwks signing I made enhancements to
credentials/Signer.go
and
credentials/SignerDefault.go
to support signing a simple
string
payload (in addition to what it currently can handle:
jwt.Claims
. The signature of the additional interface function looks like this:
Copy code
SignPayload(ctx context.Context, location *url.URL, payload string) (string, string, error)
The strings that this function returns are:
Signature
and
KeyId
. These are then used in the
authz/remote_json.go
and
authz/remote.go
to populat the associated header fields. I took an additional step to calculate the signature of the raw request body in
authz/remote.go
but since oathkeeper is intercepting (piping) an http request, the raw payload as it looked originally on the client (when the client would have generated a request signature) I feel there could be concerns upstream regarding whether the signature verification should calculate the payload signature on the raw payload or on the payload after any http transforms have been un applied e,g,: gzip compression. For this reason, I use the
remote_json
authz handler but included the
remote
handler anyway. Why? My concern isn't so much a concern over who is sending the request, my concern is more about what is being sent. I need to ensure that the endpoint processing the authz request knows that the request has not been forged by a bad actor. Simply put, I want the endpoint to be able to reasonably conclude that the message came from oathkeeper. Note, I can probably accomplish this by using
remote
and sending custom headers. But I feel like that would be a workaround for something that may be more useful if more broad configuration options were made available. I can see a use for signing payloads to other authz handlers as well. I can imagine that this could enhance security around any
hydrator
upstreams that may be in a similar situation that my legacy authz handler is in.