Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support HMAC-based authentication #8

Closed
xinz opened this issue Sep 13, 2021 · 1 comment
Closed

Support HMAC-based authentication #8

xinz opened this issue Sep 13, 2021 · 1 comment

Comments

@xinz
Copy link
Contributor

xinz commented Sep 13, 2021

Related implement by other services:

https://docs.microsoft.com/en-us/azure/azure-app-configuration/rest-api-authentication-hmac
https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html
https://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html

Proposal

Currently, looks like this is not defined in the OpenAPI v3 spec, but we need this authentication feature for use, so we plan to add an hmac-<algorithm> as the corresponding scheme field to http type of the the security scheme, because:

1, IANA maintains a list of authentication schemes does not cover hmac-related cases currently;
2, Refer the authentication schemes of Authentication from MDN, there exists other schemes offered by host services, e.g. Amazon AWS's AWS4-HMAC-SHA256 is the same level to Basic, Bearer and others in IANA maintained authentication schemes list.

Oasis uses hmac-<algorithm> scheme to define an HMAC scheme with the algorithm, hope to provide more flexible and security definition in the spec, the definition depends on your use case.

For example plan to use an hmac-sha256 authentication, the spec would be like:

openapi: 3.1.0

components:
  securitySchemes:
    hmacAuth: # arbitrary name for the security scheme
      type: http
      scheme: hmac-sha256
      x-oasis-signed-headers: x-myservice-date;host
      x-oasis-name-space: MyAuth

security:
  - hmacAuth: []
  • "x-oasis-signed-headers", required, defines HTTP request headers added to the signature, the provided headers are required in the request, and both in client/server side will use them into signature in the explicit definition order.
  • "x-oasis-name-space", optional, defines generated module's name space.

Syntax

Authorization: HMAC-uppercase(<algorithm>) Credential=<value>&SignedHeaders=<value>&Signature=<value>

Credential

ID of the access key used to signature and verify

SignedHeaders

HTTP request header names, separated by semicolons, required to sign the request in your defined order of x-oasis-signed-headers spec, the HTTP headers must be correctly provided with the request as well, do not use white spaces.

Signature

Base64 encoded HMAC-<algorithm> hash of the String-To-Sign, it uses the value(aka Secret) of the access key identified by Credential, pseudo code as below:

base64_encode(hmac-<algorithm>(String-To-Sign, Secret))

String-To-Sign

String-To-Sign is some string items concatenated as below:

String-To-Sign = HTTP_METHOD + '\n' + path_and_query + '\n' + signed_headers_values

  • HTTP_METHOD, uppercase HTTP method name used with the request.
  • path_and_query, concatenation of request absolute URI and query string.
  • signed_headers_values, semicolon-separated values of all HTTP request headers listed in SignedHeaders.

Example:

Assume we define x-oasis-signed-headers: x-myservice-date;host as a part of the security scheme, the following HTTP headers in request:

x-myservice-date: Mon, 13 Sep 2021 03:21:00 GMT
Host: www.foo.bar

In this case, the concatenated String-To-Sign as below:

String-To-Sign =
   "GET" + "\n"
   "/post?a=1&b=2" + "\n"
   "Mon, 13 Sep 2021 03:21:00 GMT;www.foo.bar"

Reference the best practices, the above example missing the key important variable Body of HTTP request, it should be used into the signature even if there is no body.

Since the way to concatenate String-To-Sign is a fixed step, we can custom a new HTTP header field to represent the Body into the SignedHeaders, and keep the value of the new field in the request for the service side verification, for example:

x-myservice-content-sha256: base64_encode(SHA256(body))
x-myservice-content-md5: base64_encode(MD5(body))

HTTP Header Contents

Host (required)

Your service endpoint, for example, "www.foo.bar"

x-myservice-date or Date (required)

You must include either x-myservice-date or Date. (Some HTTP client libraries don't let you set the Date header). When an x-myservice-date header is present, the system ignores any Date header when authenticating the request.

x-myservice-body-related

Again, refer to most HMAC-related authentication implements, the Body parameter can highlight this request, it should be used into the signature.

Once the server side is ready, we need to provide the following pair of access key to the client, to use the HTTP APIs with signature.

  • Credential - <Access Key ID>, use into the HTTP header.
  • Secret - <Access Key Secret>, can not share with anyone, use in client side signature only.
@xinz
Copy link
Contributor Author

xinz commented Jul 21, 2022

Released in 0.5.0

@xinz xinz closed this as completed Jul 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant