Openapi-specification: Specifying HMAC-based authentication in the spec

Created on 27 Apr 2015  路  21Comments  路  Source: OAI/OpenAPI-Specification

The current spec (v2.0) defines three valid security schemes: basic HTTP authentication, authentication using an API key, and Oauth2.

What seems to be nonexistent is an HMAC-based authentication scheme. Are there any plans to add such a scheme in the upcoming versions of the spec?

OpenAPI.Next Proposal Sub Issue

Most helpful comment

It would be nice to see something a bit more free-form and generic implemented here.

Perhaps it would be sufficiently flexible to allow the API spec authors to define which parameters, and their formats, are required for the hash inputs. This would be able to support HMAC-like schemes such as Hawk.

Something like this:

{
    "securityDefinitions" : {
        "hmac-ish": {
            "hashInputParameters" : {
                "timestamp" : {
                  "type" : "integer",
                  "format" : "int64"
                },
                "uri" : {
                    "type" : "string",
                    "description" : "The full URI of the request"
                },
                "body" : {
                    "type" : "object",
                    "description" : "The full body payload of the request"
                },
                ...
            },
            "hashAlgorithm":"sha256",
            "hashOutputParameter" : {
                "name" : "myHash",
                "in" : "header",
                "description": "Holds the hash"
                ...
            }
        },
        "otherHashingSecurityDefinition": {
            "hashInputParameters" : {
                "uri" : {
                    "type" : "string",
                    "description" : "The full URI of the request"
                },
                ...
            },
            "hashAlgorithm":"sha1",
            "hashOutputParameter" : {
                "name" : "myOtherHash",
                "in" : "header",
                "description": "Holds the hash"
                ...
            }
        }
    }
}

All 21 comments

:+1: Would be really nice to have better support for HMAC.

@bow - it would help to know what would be required to support HMAC. Don't really know the specifics of it.

Ah indeed, HMAC is too broad of a term. I'll try to elaborate more what I had mind:

I was looking for a way to authenticate some of my end points using a digest-based scheme. I stumbled on Amazon's API authentication scheme, but I have the impression they are inventing their own standard (which is something I hope to avoid). Looking further,
I see that there is already a digest authentication scheme defined in RFC2617. Considering this is a known standard, I was hoping that the swagger spec allows me to document such a scheme.

In short, something which allows me to specify that for some endpoints, something like:

Authorization: Digest response=384729837942...

is required in the request header.

(apologies if my terminology gets unclear ~ as you can probably guess, I'm not a cryptography expert ;) ).

No worries. It's been a long time since I've read up on Digest authentication so will have to go over it again at some point.

If you already know, what is the value given as the response (assuming response is something fixed in the header)?

response is something optional in the header (per the RFC). The requirement is that at least one key-value pair from several choices are defined (section 3.2.2) in Authorization, response being one of them.

The contents itself, when defined, is the hash. What needs to be hashed depends on the value of other optional keys as well (section 3.2.2.1).

Right, but the question is whether the spec (Swagger) needs to define which key-values are required for the Digest authentication scheme, as for the values, what they need to contain.

If there are suggestions on how to generalize a HMAC implementation I think we'd be happy to include it in the next rev of the spec. All the mechanisms are there to automatically generate the hashes.

@webron If I can say, I'd try to be as close as possible to the RFC.

However, the RFC keys seems to have quite complex dependencies among each other (e.g. cnonce must be specified if qop is specified but must not be specified otherwise). So I can imagine this can complicate the Swagger spec too much. In this case, maybe a sensible alternative would be to aim for a subset of what the RFC allows. So at least the username, realm, password, digest-uri, and nonce must be specified. You may notice that this makes for a valid authentication scheme based on an earlier RFC, RFC2069, which RFC2617 supersedes.

This could complicate things when qop is specified, though. Also, what's missing from the Digest authentication scheme is a non-MD5 hashing method (so @fehguy , this isn't exactly HMAC as I thought earlier) since the RFC only recognizes MD5. So while this is technically digest, it's not as general as some would want.

If these two alternatives are too complicated, maybe it's simply simpler to update the swagger spec with a more general Authorization header specification? Something like adding a custom security scheme where the value of the Authorization header is essentially free form text?

It would be nice to see something a bit more free-form and generic implemented here.

Perhaps it would be sufficiently flexible to allow the API spec authors to define which parameters, and their formats, are required for the hash inputs. This would be able to support HMAC-like schemes such as Hawk.

Something like this:

{
    "securityDefinitions" : {
        "hmac-ish": {
            "hashInputParameters" : {
                "timestamp" : {
                  "type" : "integer",
                  "format" : "int64"
                },
                "uri" : {
                    "type" : "string",
                    "description" : "The full URI of the request"
                },
                "body" : {
                    "type" : "object",
                    "description" : "The full body payload of the request"
                },
                ...
            },
            "hashAlgorithm":"sha256",
            "hashOutputParameter" : {
                "name" : "myHash",
                "in" : "header",
                "description": "Holds the hash"
                ...
            }
        },
        "otherHashingSecurityDefinition": {
            "hashInputParameters" : {
                "uri" : {
                    "type" : "string",
                    "description" : "The full URI of the request"
                },
                ...
            },
            "hashAlgorithm":"sha1",
            "hashOutputParameter" : {
                "name" : "myOtherHash",
                "in" : "header",
                "description": "Holds the hash"
                ...
            }
        }
    }
}

Not sure if this is directly applicable or not, but there is an IETF RFC draft that adds support to retrieving resources using MAC tokens to Oauth2.

I second this request, as I need this for my project -- would be awesome to have support for this in ui/editor.

Couldn't you just do something fairly simple + generic here? I'm thinking it could be done by allowing one to specify a callback JavaScript function that receives the outbound request and allows the function to modify / sign it before being sent.

Possibly as simple as adding a new type to the Security Scheme Object like custom, and add a new field callback that specifies a string function:

{
   "type": "custom",
   "callback": "function (req) { /* manipulate request on the way out */ }"
}

To support it in the editor, the callback would have to be eval'd

This way, the spec punts the implementation and allows the api designer to implement whatever signing protocol they intend to use.

I second @bow suggestion on having an quick way to support Authorization Header with custom security scheme. This could be a better starting point.

This can further evolve into what @who has suggested. This is more robust and complete support for such authentication mechanisms.

Going through the following SO questions and Amazon suggested implementation of this approach, IMHO, the above two could be a better way forward

http://stackoverflow.com/questions/454355/security-of-rest-authentication-schemes
http://stackoverflow.com/questions/14043397/http-basic-authentication-instead-of-tls-client-certification
http://stackoverflow.com/questions/319530/restful-authentication

http://docs.aws.amazon.com/general/latest/gr/sigv4-signed-request-examples.html

This should probably be associated https://github.com/OAI/OpenAPI-Specification/issues/585

Thanks @who! Parent is indeed: #585.

@webron Definitely interested in helping this move forward. Many of the projects on which I work will need an HMAC authentication mechanism.

I'd be glad to put together real-world use cases for this. If those would be useful, where would one contribute them? Should I just create a gist/md with nicely-formatted explanations and examples?

@who - sure, gists would be great. Anything that helps clarifying and moving the discussion forward.

pr #807 now allows you to identify any HTTP scheme in the security definition. There are so many different variants of how HMAC tokens are generated, it would be problematic to try and specify all possibilities. x- properties can be used to identify parameters that are specific to a particular scheme.

We've done what we could :)

hi guys,
what is the outcome of this issue? i also do need this feature. Is there any workaround for that?
I simply want my clients to pass (ie HMAC-SHA512) signature of the request body, so i'm sure, the message was not modified on its way to the server.

I need this feature as well.

Hi Guys,
I am also interested in this feature.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

muhmud picture muhmud  路  5Comments

jblazek picture jblazek  路  3Comments

rocchisanijl picture rocchisanijl  路  5Comments

nelz9999 picture nelz9999  路  4Comments

mission-liao picture mission-liao  路  3Comments