Skip to content
This repository has been archived by the owner on Nov 18, 2024. It is now read-only.

Commit

Permalink
Merge pull request #37 from puppetlabs/features/device-grant
Browse files Browse the repository at this point in the history
Implement device code grant type
  • Loading branch information
impl authored Mar 24, 2021
2 parents 6b0c6e2 + a63735a commit c21baac
Show file tree
Hide file tree
Showing 32 changed files with 2,650 additions and 608 deletions.
61 changes: 48 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@
This is a standalone backend plugin for use with [HashiCorp
Vault](https://github.com/hashicorp/vault).

This plugin provides a secure wrapper around OAuth 2 authorization code grant
flows, allowing a Vault client to request authorization on behalf of a user and
perform actions using a negotiated OAuth 2 access token.
This plugin provides a secure wrapper around OAuth 2 authorization code, refresh
token, device code, and client credentials grant types, allowing a Vault client
to request authorization on behalf of a user and perform actions using a
negotiated OAuth 2 access token.

## Usage

Expand Down Expand Up @@ -72,10 +73,38 @@ write instead of the response code:

```console
$ vault write oauth2/bitbucket/creds/my-user-auth \
grant_type=refresh_token \
refresh_token=TGUgZ3JpbGxlPw==
Success! Data written to: oauth2/bitbucket/creds/my-user-auth
```

### Device code flow

The [device code](https://oauth.net/2/grant-types/device-code/) grant type
allows a user to authenticate outside of a browser session. This plugin supports
the device code flow and automatically handles polling the authorization server
for a valid access token.

Not all providers support device code grants. Check the provider's documentation for more information.

To initiate the device code flow (this time using [GitHub as an
example](https://docs.github.com/en/developers/apps/authorizing-oauth-apps#device-flow)):

```console
$ vault write oauth2/github/creds/my-user-auth grant_type=urn:ietf:params:oauth:grant-type:device_code
Key Value
--- -----
user_code BDWD-HQPK
verification_uri https://github.com/login/device
expire_time 2021-03-10T23:35:00.295229233Z
```

The plugin will manage the device code (similar to a refresh token) and will
never present it to you. You should forward the user code and verification URL
to the authorization subject for them to take action to log in.

XXX: Finish this once we have the errors nailed down.

### Client credentials flow

From a Vault client, simply read an arbitrary token using the `self` endpoints:
Expand Down Expand Up @@ -126,7 +155,7 @@ configuration, so you must specify all required fields, even when updating.
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|----------|
| `client_id` | The OAuth 2.0 client ID. | String | None | Yes |
| `client_secret` | The OAuth 2.0 client secret. | String | None | Yes |
| `client_secret` | The OAuth 2.0 client secret. | String | None | No |
| `auth_url_params` | A map of additional query string parameters to provide to the authorization code URL. | Map of String🠦String | None | No |
| `provider` | The name of the provider to use. See [the list of providers](#providers). | String | None | Yes |
| `provider_options` | Options to configure the specified provider. | Map of String🠦String | None | No |
Expand Down Expand Up @@ -154,8 +183,8 @@ endpoint will return an error.

### `creds/:name`

This path is for tokens to be obtained using the OAuth 2.0 authorization code
and refresh token flows.
This path is for tokens to be obtained using the OAuth 2.0 authorization code,
refresh token, and device code flows.

#### `GET` (`read`)

Expand All @@ -172,17 +201,22 @@ using the `refresh_token` grant type if possible.

#### `PUT` (`write`)

Create or update a credential after an authorization code flow has returned to
the application. This request will make a request for a new credential using the
`authorization_code` grant type.
Create or update a credential using a supported three-legged flow. This
operation will make a request for a new credential using the specified grant
type.

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|----------|
| `code` | The response code to exchange for a full token. | String | None | Either this or `refresh_token` |
| `redirect_url` | The same redirect URL as specified in the authorization code URL. | String | None | Refer to provider documentation |
| `refresh_token` | A refresh token retrieved from the provider by some means external to this plugin. | String | None | Either this or `code` |
| `grant_type` | The grant type to use. Must be one of `authorization_code`, `refresh_token`, or `urn:ietf:params:oauth:grant-type:device_code`. | String | `authorization_code`* | No |
| `code` | For authorization code flow, the response code to exchange for a full token. | String | None | If `grant_type` is `authorization_code` |
| `redirect_url` | For authorization code flow, the same redirect URL as specified in the authorization code URL. | String | None | Refer to provider documentation |
| `refresh_token` | For refresh token flow, the refresh token retrieved from the provider by some means external to this plugin. | String | None | If `grant_type` is `refresh_token` |
| `device_code` | For device code flow, a device code that has already been retrieved. If not specified, a new device code will be retrieved. | String | None | No |
| `scopes` | For device code flow, the scopes to request. | List of String | None | No |
| `provider_options` | A list of options to pass on to the provider for configuring this token exchange. | Map of String🠦String | None | Refer to provider documentation |

\* For compatibility, if `grant_type` is not provided and `refresh_token` is set, the `grant_type` will default to `refresh_token`.

#### `DELETE` (`delete`)

Remove the credential information from storage.
Expand Down Expand Up @@ -271,7 +305,7 @@ This provider implements the OpenID Connect protocol version 1.0.

| Name | Description | Default | Required |
|------|-------------|---------|----------|
| `nonce` | The same nonce as specified in the authorization code URL. | String | None | If present in the authorization code URL |
| `nonce` | The same nonce as specified in the authorization code URL. | None | If present in the authorization code URL |

### Slack (`slack`)

Expand All @@ -287,5 +321,6 @@ arbitrary OAuth 2 authorization code grant flow.
| Name | Description | Default | Required |
|------|-------------|---------|----------|
| `auth_code_url` | The URL to submit the initial authorization code request to. | None | No |
| `device_code_url` | The URL to subject a device authorization request to. | None | No |
| `token_url` | The URL to use for exchanging temporary codes and refreshing access tokens. | None | Yes |
| `auth_style` | How to authenticate to the token URL. If specified, must be one of `in_header` or `in_params`. | Automatically detect | No |
5 changes: 4 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ require (
github.com/hashicorp/vault/sdk v0.1.14-0.20190909201848-e0fbf9b652e2
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
github.com/puppetlabs/leg/errmap v0.1.0
github.com/puppetlabs/leg/scheduler v0.2.1
github.com/puppetlabs/leg/timeutil v0.4.0
github.com/spf13/afero v1.2.2 // indirect
github.com/stretchr/testify v1.6.1
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
google.golang.org/appengine v1.6.2 // indirect
google.golang.org/grpc v1.23.1 // indirect
gopkg.in/square/go-jose.v2 v2.3.1
gotest.tools/gotestsum v0.6.0
k8s.io/apimachinery v0.20.1
)
Loading

0 comments on commit c21baac

Please sign in to comment.