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

Add client credentials flow example to readme #640

Merged
merged 8 commits into from
Dec 8, 2023
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,27 @@ This will poll in the defined interval and only resolve with a TokenSet once one
will handle the defined `authorization_pending` and `slow_down` "soft" errors and continue polling
but upon any other error it will reject. With tokenSet received you can throw away the handle.

### Client Credentials Grant Flow

Exchanging the client_id and client_secret of your application for an access token, to authenticate
at a third-party api. Not on behalf of a user. Suitable for Machine-to-Machine authentication.
panva marked this conversation as resolved.
Show resolved Hide resolved

**See the [documentation][] for full API details.**
sezanzeb marked this conversation as resolved.
Show resolved Hide resolved

```js
const client = new googleIssuer.Client({
panva marked this conversation as resolved.
Show resolved Hide resolved
client_id: 'zELcpfANLqY7Oqas',
client_secret: 'TQV5U29k1gHibH5bx1layBo0OSAvAbRT3UYW3EWrSYBB5swxjVfWUa1BS8lqzxG/0v9wruMcrGadany3',
redirect_uris: ['http://localhost:3000/cb'],
response_types: ['code']
sezanzeb marked this conversation as resolved.
Show resolved Hide resolved
});

const tokenSet = await client.grant({
audience: 'insert-your-audience',

This comment was marked as outdated.

This comment was marked as outdated.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
audience: 'insert-your-audience',
resource: 'urn:example:third-party-api',

Copy link
Contributor Author

@sezanzeb sezanzeb Dec 1, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking into the auth0 web ui, the thing that jumps into view multiple times is the audience, and the quickstart shows it with an audience.

I tried to find something about this resource string in auth0 and by searching the internet, but couldn't. I also tried to look into the code, but the type of the grant function is just

export interface GrantBody {
  grant_type: string;

  [key: string]: unknown;
}

In there readme it mentions

client.authorizationUrl({
  scope: 'openid email profile',
  resource: 'https://my.api.example.com/resource/32178',

Is the resource in that case "32178"?

So I have no idea what the resource string is, and I definitely would want to see where to put the audience in the example.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

auth0 mentions an urn in the context of SAML: https://auth0.com/blog/url-uri-urn-differences/

the wikipedia entry says SAML is important for SSO: https://en.wikipedia.org/wiki/Security_Assertion_Markup_Language

Is this really relevant for the client credentials flow?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

@sezanzeb sezanzeb Dec 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It appears that (for example) auth0 doesn't implement this yet (https://community.auth0.com/t/support-rfc-8707/66169). I really think it would be beneficial to document both options. OAuth was very complicated (at least for me) to figure out, because of the plethora of variants, and I'm pretty sure I won't be the last person to search the docs and/or readme for "audience". So I think it's better to give more hints.

I made a commit that at least mentions both properties in docs/README.md

One could still also mention them in the readme like this, but as long as it is at least mentioned somewhere, I don't mind commiting your proposal without audience.

Suggested change
audience: 'insert-your-audience',
audience: 'example', // optional
resource: 'urn:example:third-party-api', // optional, for RFC 8707 compatibility

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sezanzeb This repo's history will show you that it's aim is to support the OIDC Conforming behaviour as RP.

That means couple of things:

  • SHOULD promote conforming use cases, like suggesting RFC 8707 way of asking for a resource when those OPs implement RFC 8707.
  • Should NOT promote any edge cases for different OP implementations around.
    Auth0 is OIDC provider vendor, but it's not conforming to 8707 spec as described.
    For example, I may not be using Auth0 as my OP, I may or may not be using grant function, and I don't want to be mislead into having to think about audience parameter at all in those cases.
    So that's a rationale why audience should not land in docs in this library. More like in your server implementation repo is where the place for those docs is.
  • Should NOT prevent you from passing extra parameters when those are required. It's also stated in types with this type descriptor: [key: string]: unknown;, that's why typescript is not complaining when you add audience. Also, you can look at source code and see that all arguments you define are in fact being passed to provider.

Copy link
Contributor Author

@sezanzeb sezanzeb Dec 7, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should NOT promote any edge cases for different OP implementations around.

This is for giving hints for less knowledgeable people like me. I'm not a specialist for oauth, and my intention for using a library is, that it will help me set things up correctly without having to have a solid understanding of the thing at hand.

Actually, I don't remember where I even got the idea that I can insert audience there. Might just have been a random comment somewhere that I found by pure luck, or I probably used my previous code as a reference, which was making the request via axios and correctly used audience already.

AuthorizationParameters has audience?: string; in its interface by the way.

I made another commit, this time removing audience from README.md, and saying that audience is non-standard in docs/README.md

grant_type: 'client_credentials'
});
```

## FAQ

#### Semver?
Expand Down