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

Commit 09465f2

Browse files
authored
Merge pull request #56 from puppetlabs/improvements/tuning
Performance tuning options
2 parents 197ce24 + 356ad49 commit 09465f2

23 files changed

+1736
-98
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ Versioning](https://semver.org/spec/v2.0.0.html).
88

99
## [Unreleased]
1010

11+
### Added
12+
13+
* Add additional performance tuning options for provider timeouts and automatic credential reaping.
14+
1115
## [2.1.1] - 2021-06-25
1216

1317
### Fixed

README.md

Lines changed: 107 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,6 @@ $ vault write oauth2/bitbucket/config/self/my-machine-auth \
151151
Success! Data written to: oauth2/bitbucket/config/self/my-machine-auth
152152
```
153153

154-
### Automatic refresh checking
155-
156-
By default tokens are automatically checked for refresh every 60
157-
seconds. You can change that interval by setting the
158-
`tune_refresh_check_interval_seconds` config option to another number of
159-
seconds. If set to zero, tokens will be refreshed only on demand.
160-
161154
## Tips
162155

163156
For some operations, you may find that you need to provide a map of data for a
@@ -170,6 +163,79 @@ $ vault write oauth2/oidc/config \
170163
provider_options=extra_data_fields=id_token_claims
171164
```
172165

166+
## Performance tuning
167+
168+
There are several categories of performance tuning options you may want to
169+
adjust to get the most out of this plugin. All of the options are fields set
170+
when writing this plugin's configuration to the `config` endpoint.
171+
172+
### Provider timeouts
173+
174+
It can be inconvenient when a provider you're working with doesn't respond to
175+
requests in a reasonable time. Therefore, we apply a default timeout of 30
176+
seconds to all outbound requests. We also allow for a bit of leeway when a token
177+
is getting close to its expiry, preferring to wait longer to avoid clients
178+
having to retry requests to Vault. This is applied using a logarithmic algorithm
179+
relative to the usual grace period we'd use for refreshing.
180+
181+
You can set the initial provider timeout using the
182+
`tune_provider_timeout_seconds` option. If you set it to 0, we won't apply any
183+
timeout.
184+
185+
The default leeway factor is 1.5, i.e., a maximum timeout of 45 seconds when a
186+
token is close to expiration. You can set a different factor using the
187+
`tune_provider_timeout_expiry_leeway_factor` option. To disable timeout scaling,
188+
set the leeway factor to 1.
189+
190+
### Automatic refreshing
191+
192+
To avoid having to contact providers when tokens are read from storage and need
193+
to be refreshed, this plugin will automatically check and attempt to refresh
194+
tokens that are close to expiring on a regular interval. The default check
195+
interval is 1 minute. The refresh check has a grace period, called the expiry
196+
delta, that extends beyond the refresh check interval to allow for some overlap.
197+
The default expiry delta factor is 1.2, or 72 seconds.
198+
199+
You can set the refresh check interval using the
200+
`tune_refresh_check_interval_seconds` option and the expiry delta factor using
201+
the `tune_refresh_expiry_delta_factor` option.
202+
203+
If you don't need this behavior, for example because your provider doesn't use
204+
refresh tokens, you can set `tune_refresh_check_interval_seconds` to 0.
205+
206+
Alternatively, if you have a relatively small number of tokens and your provider
207+
issues tokens with very long expirations, you may want to use a longer refresh
208+
interval than the default to avoid having to loop over all credentials in
209+
storage every minute.
210+
211+
### Automatic reaping
212+
213+
There are a number of situations that result in stored tokens becoming unusable.
214+
Broadly, we group these into the following categories:
215+
216+
* Expired with no refresh token
217+
* Expired and refresh failed because the provider rejected the refresh request
218+
* Expired and enough transient errors have occurred to discard the token (for
219+
example, instead of rejecting a token, the provider hangs the connection)
220+
221+
This plugin can automatically delete tokens that are expired and meet one of
222+
these criteria using a process called reaping. Like the automatic refreshing,
223+
reaping runs on an interval, by default 5 minutes. You can change the reap
224+
interval using the `tune_reap_check_interval_seconds` option.
225+
226+
You can disable the reaper entirely by setting the option to 0, or you can
227+
enable a dry run mode using the `tune_reap_dry_run` option. When in dry run
228+
mode, you can check your Vault server logs to see which credentials would be
229+
deleted.
230+
231+
The criteria are mutually exclusive, so for example, a token that has a provider
232+
refresh rejection will always have that criterion applied to it, even if it also
233+
has transient errors.
234+
235+
Each of the criteria have their own tuning options documented in the `config`
236+
endpoint. Note that the defaults should be reasonable for most users. You can
237+
disable any of the criteria by setting its corresponding option to 0.
238+
173239
## Endpoints
174240

175241
### `config`
@@ -191,12 +257,21 @@ configuration, so you must specify all required fields, even when updating.
191257
| `provider` | The name of the provider to use. See [the list of providers](#providers). | String | None | Yes |
192258
| `provider_options` | Options to configure the specified provider. | Map of String🠦String | None | No |
193259

194-
There is also an additional configuration option that may be set for
195-
fine tuning.
260+
In addition to basic configuration, this endpoint allows you to set performance
261+
and application-specific tuning options for the plugin:
196262

197-
| Name | Description | Type | Default |
198-
|------|-------------|------|---------|
199-
| `tune_refresh_check_interval_seconds` | Number of seconds between checking tokens for refresh. | Integer | 60 |
263+
| Name | Description | Type | Default | Required |
264+
|------|-------------|------|---------|----------|
265+
| `tune_provider_timeout_seconds` | Maximum duration to wait for a response from the provider for background credential operations. | Integer | 30 | No |
266+
| `tune_provider_timeout_expiry_leeway_factor` | A multiplier for the `tune_provider_timeout_seconds` option to allow a slow provider to respond as a credential approaches expiration. Must be at least 1. | Number | 1.5 | No |
267+
| `tune_refresh_check_interval_seconds` | Number of seconds between checking tokens for refresh. Set to 0 to disable automatic background refreshing. | Integer | 60 | No |
268+
| `tune_refresh_expiry_delta_factor` | A multiplier for the refresh check interval to use to detect tokens that will expire soon after the impending refresh. Must be at least 1. | Number | 1.2 | No |
269+
| `tune_reap_check_interval_seconds` | Number of seconds between running the reaper process. Set to 0 to disable automatic reaping of expired credentials. | Integer | 300<sup id="ret-1">[1](#footnote-1)</sup> | No |
270+
| `tune_reap_dry_run` | If set, the reaper process will only report which credentials it would remove, but not actually delete them from storage. | Boolean | False | No |
271+
| `tune_reap_non_refreshable_seconds` | Minimum additional time to wait before automatically deleting an expired credential that does not have a refresh token. Set to 0 to disable this reaping criterion. | Integer | 86400 | No |
272+
| `tune_reap_revoked_seconds` | Minimum additional time to wait before automatically deleting an expired credential that has a revoked refresh token. Set to 0 to disable this reaping criterion. | Integer | 3600 | No |
273+
| `tune_reap_transient_error_attempts` | Minimum number of refresh attempts to make before automatically deleting an expired credential. Set to 0 to disable this reaping criterion. | Integer | 10 | No |
274+
| `tune_reap_transient_error_seconds` | Minimum additional time to wait before automatically deleting an expired credential that cannot be refreshed because of a transient problem like network connectivity issues. Set to 0 to disable this reaping criterion. | Integer | 86400 | No |
200275

201276
#### `DELETE` (`delete`)
202277

@@ -218,7 +293,7 @@ endpoint will return an error.
218293
| `redirect_url` | The URL to redirect to once the user has authorized this application. | String | None | No |
219294
| `scopes` | A list of explicit scopes to request. | List of String | None | No |
220295
| `state` | The unique state to send to the authorization URL. | String | None | Yes |
221-
| `provider_options` | A list of options to pass on to the provider for configuring the authorization code URL. | Map of String🠦String | None | None |
296+
| `provider_options` | A list of options to pass on to the provider for configuring the authorization code URL. | Map of String🠦String | None | No |
222297

223298
### `config/self/:name`
224299

@@ -237,7 +312,7 @@ the `client_credentials` grant type.
237312
|------|-------------|------|---------|----------|
238313
| `token_url_params` | A map of additional query string parameters to provide to the token URL. If any keys in this map conflict with the parameters stored in the configuration, the configuration's parameters take precedence. | Map of String🠦String | None | No |
239314
| `scopes` | A list of explicit scopes to request. | List of String | None | No |
240-
| `provider_options` | A list of options to pass on to the provider for configuring this token exchange. | Map of String🠦String | None | None |
315+
| `provider_options` | A list of options to pass on to the provider for configuring this token exchange. | Map of String🠦String | None | No |
241316

242317
#### `DELETE` (`delete`)
243318

@@ -257,10 +332,7 @@ using the `refresh_token` grant type if possible.
257332

258333
| Name | Description | Type | Default | Required |
259334
|------|-------------|------|---------|----------|
260-
| `minimum_seconds` | Minimum seconds before access token expires | Integer | * | No |
261-
262-
\* Defaults to underlying library default, which is 10 seconds unless
263-
the token expiration time is set to zero.
335+
| `minimum_seconds` | Minimum additional duration to require the access token to be valid for. | Integer | 10<sup id="ret-2-a">[2](#footnote-2)</sup> | No |
264336

265337
#### `PUT` (`write`)
266338

@@ -270,7 +342,7 @@ type.
270342

271343
| Name | Description | Type | Default | Required |
272344
|------|-------------|------|---------|----------|
273-
| `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 |
345+
| `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`<sup id="ret-3">[3](#footnote-3)</sup> | No |
274346
| `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 |
275347

276348
This operation takes additional fields depending on which grant type is chosen:
@@ -295,8 +367,6 @@ This operation takes additional fields depending on which grant type is chosen:
295367
| `device_code` | A device code that has already been retrieved. If not specified, a new device code will be retrieved. | String | None | No |
296368
| `scopes` | If a device code is not specified, the scopes to request. | List of String | None | No |
297369

298-
\* For compatibility, if `grant_type` is not provided and `refresh_token` is set, the `grant_type` will default to `refresh_token`.
299-
300370
#### `DELETE` (`delete`)
301371

302372
Remove the credential information from storage. This does not delete the
@@ -316,10 +386,7 @@ new credential using the `client_credentials` grant type.
316386

317387
| Name | Description | Type | Default | Required |
318388
|------|-------------|------|---------|----------|
319-
| `minimum_seconds` | Minimum seconds before access token expires | Integer | * | No |
320-
321-
\* Defaults to underlying library default, which is 10 seconds unless
322-
the token expiration time is set to zero.
389+
| `minimum_seconds` | Minimum additional duration to require the access token to be valid for. | Integer | 10<sup id="ret-2-b">[2](#footnote-2)</sup> | No |
323390

324391
#### `DELETE` (`delete`)
325392

@@ -413,3 +480,18 @@ arbitrary OAuth 2 authorization code grant flow.
413480
| `device_code_url` | The URL to subject a device authorization request to. | None | No |
414481
| `token_url` | The URL to use for exchanging temporary codes and refreshing access tokens. | None | Yes |
415482
| `auth_style` | How to authenticate to the token URL. If specified, must be one of `in_header` or `in_params`. | Automatically detect | No |
483+
484+
485+
## Footnotes
486+
487+
<span id="footnote-1"><sup>1</sup> For users upgrading from versions prior to
488+
2.2.0 with valid configurations, the reaper will not be automatically enabled
489+
unless you replace your configuration. <small>[](#ret-1)</small></span>
490+
491+
<span id="footnote-2"><sup>2</sup> The default is 10 seconds as specified in the
492+
Go [OAuth 2.0 library](https://github.com/golang/oauth2) unless the token does
493+
not expire. <small>↩ [a](#ret-2-a) [b](#ret-2-b)</small></span>
494+
495+
<span id="footnote-3"><sup>3</sup> For compatibility, if `grant_type` is not
496+
provided and `refresh_token` is set, the `grant_type` will default to
497+
`refresh_token`. <small>[](#ret-3)</small></span>

go.mod

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,19 @@ require (
66
github.com/coreos/go-oidc v2.2.1+incompatible
77
github.com/golangci/golangci-lint v1.33.0
88
github.com/hashicorp/errwrap v1.1.0 // indirect
9-
github.com/hashicorp/go-hclog v0.8.0
10-
github.com/hashicorp/golang-lru v0.5.3 // indirect
11-
github.com/hashicorp/vault/api v1.0.4
12-
github.com/hashicorp/vault/sdk v0.1.14-0.20190909201848-e0fbf9b652e2
9+
github.com/hashicorp/go-hclog v0.14.1
10+
github.com/hashicorp/vault/api v1.0.5-0.20200519221902-385fac77e20f
11+
github.com/hashicorp/vault/sdk v0.2.0
12+
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect
1313
github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect
1414
github.com/puppetlabs/leg/errmap v0.1.0
1515
github.com/puppetlabs/leg/scheduler v0.3.0
16-
github.com/puppetlabs/leg/timeutil v0.4.1
16+
github.com/puppetlabs/leg/timeutil v0.4.2
1717
github.com/spf13/afero v1.2.2 // indirect
1818
github.com/stretchr/testify v1.6.1
1919
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45
2020
google.golang.org/appengine v1.6.2 // indirect
21-
gopkg.in/square/go-jose.v2 v2.3.1
21+
gopkg.in/square/go-jose.v2 v2.5.1
2222
gotest.tools/gotestsum v0.6.0
2323
k8s.io/apimachinery v0.20.1
2424
)

0 commit comments

Comments
 (0)