Skip to content

Commit 5c1337d

Browse files
authored
Merge pull request #162 from dotkernel/oauth2-keys-and-revocation
Correct OAuth2 key generation and token revocation in v7 docs
2 parents a25cc46 + 5a17e0d commit 5c1337d

1 file changed

Lines changed: 38 additions & 12 deletions

File tree

‎docs/book/v7/security/oauth2-security.md‎

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
## Summary
44

5-
The security steps to take before an OAuth2-protected Dotkernel API reaches production: remove or re-password the default `admin` and `frontend` OAuth clients, tune access and refresh token lifetimes, and understand how the JWT signing key pair is regenerated and where it must be kept.
5+
The security steps to take before an OAuth2-protected Dotkernel API reaches production: remove or re-password the default `admin` and `frontend` OAuth clients, tune access and refresh token lifetimes, and understand how the JWT signing key pair is generated, why existing keys are preserved, and where they must be kept.
66

77
## Details
88

@@ -22,19 +22,36 @@ The configuration for OAuth2 tokens can be edited in `config/autoload/local.php`
2222
By default, the lifetimes of the `access` and `refresh` tokens are set to one day and one month respectively.
2323
Make sure to adjust their values in accordance with your application's needs, with lower values being generally safer.
2424

25-
> If your application requires it, you can revoke user OAuth tokens before their expiration by making use of the `revokeTokens` method of `UserService`.
25+
> If your application requires it, you can revoke a user's OAuth tokens before they expire.
26+
> `UserService::revokeTokens()` is `private`, so it cannot be called from your own code; it runs as part of the public `UserService::deleteUser()`, which revokes the tokens and then anonymizes the account.
27+
>
28+
> To revoke tokens on their own, use the token repositories directly: fetch the user's tokens with `OAuthAccessTokenRepository::findAccessTokens($identity)`, then pass each token to `OAuthAccessTokenRepository::revokeAccessToken()` and `OAuthRefreshTokenRepository::revokeRefreshToken()`.
2629
>
2730
> Read more about the available [configuration options](https://docs.mezzio.dev/mezzio-authentication-oauth2/v1/intro/#configuration).
2831
2932
## Autogeneration of Cryptographic Keys
3033

31-
Dotkernel API makes use of the `./vendor/bin/generate-oauth2-keys` command from `mezzio-authentication-oauth2` to automatically regenerate the
32-
public/private key pair used to verify the transmitted JWTs.
33-
This process is done after each `composer update` (or `composer install` with no lock file), as specified in `composer.json` under the `scripts.post-update-cmd` key.
34+
Dotkernel API runs its own `php ./bin/generate-oauth2-keys.php` script to create the public/private key pair and the encryption key used to sign and verify the transmitted JWTs.
35+
It is invoked after each `composer update` (or `composer install` with no lock file), as specified in `composer.json` under the `scripts.post-update-cmd` key:
36+
37+
```json
38+
"post-update-cmd": [
39+
"php ./bin/generate-oauth2-keys.php",
40+
"php ./bin/composer-post-install-script.php"
41+
]
42+
```
43+
44+
**Existing keys are never overwritten.**
45+
The script checks for `data/oauth/encryption.key`, `data/oauth/private.key` and `data/oauth/public.key`; if all three are present it prints `OAuth2 keys already exist. Skipping...` and stops.
46+
Only when one is missing does it delegate to `vendor/mezzio/mezzio-authentication-oauth2/bin/generate-oauth2-keys` to generate the set.
47+
48+
> This guard matters in production: regenerating the keys invalidates every access token already issued.
49+
> Preserving them across updates was added in Dotkernel API 7.2.0 ([issue #503](https://github.com/dotkernel/api/issues/503)).
50+
> If you deliberately want to rotate the keys, delete the three files from `data/oauth` and run `composer update` — accepting that existing tokens stop working.
3451
3552
While hidden to the VCS by default, keep in mind not to commit any local keys.
3653

37-
> Autogeneration of keys can be disabled by simply removing the `php ./vendor/bin/generate-oauth2-keys` command from the mentioned key.
54+
> Key generation can be disabled by removing the `php ./bin/generate-oauth2-keys.php` entry from the mentioned key.
3855
>
3956
> While not related to Dotkernel API itself, do ensure that the directory containing the keys is properly secured.
4057
@@ -52,16 +69,25 @@ Defaults are one day for access tokens and one month for refresh tokens; shorter
5269

5370
**Q: Can I invalidate a user's tokens before they expire?**
5471

55-
A: Yes, via the `revokeTokens` method of `UserService`.
72+
A: Yes, but not via `UserService::revokeTokens()` — that method is `private`.
73+
It runs as part of the public `UserService::deleteUser()`, which also anonymizes the account.
74+
To revoke tokens on their own, use the repositories: `OAuthAccessTokenRepository::findAccessTokens($identity)` to list them, then `revokeAccessToken()` and `OAuthRefreshTokenRepository::revokeRefreshToken()` for each.
75+
76+
**Q: When are the OAuth2 keys generated?**
77+
78+
A: `php ./bin/generate-oauth2-keys.php` runs after every `composer update`, and after `composer install` when there is no lock file, via `scripts.post-update-cmd` in `composer.json`.
79+
It only generates keys that are missing: if all three files in `data/oauth` exist it reports `OAuth2 keys already exist. Skipping...` and leaves them alone, so updating dependencies does not invalidate issued tokens.
5680

57-
**Q: When are the OAuth2 keys regenerated?**
81+
**Q: How do I stop the keys from being generated?**
5882

59-
A: After every `composer update`, and after `composer install` when there is no lock file, through the `php ./vendor/bin/generate-oauth2-keys` script in `composer.json`.
83+
A: Remove `php ./bin/generate-oauth2-keys.php` from the `scripts.post-update-cmd` key in `composer.json`.
84+
Since 7.2.0 this is rarely necessary — the script already preserves existing keys, which is what protects issued tokens on a server.
6085

61-
**Q: How do I stop the keys from being regenerated?**
86+
**Q: How do I deliberately rotate the keys?**
6287

63-
A: Remove `php ./vendor/bin/generate-oauth2-keys` from the `scripts.post-update-cmd` key in `composer.json`.
64-
This matters on servers where regenerating keys would invalidate tokens already issued.
88+
A: Delete `encryption.key`, `private.key` and `public.key` from `data/oauth`, then run `composer update`.
89+
The script regenerates the missing set.
90+
Every access token issued under the old keys stops working, so plan for clients to re-authenticate.
6591

6692
**Q: Should the key pair be committed?**
6793

0 commit comments

Comments
 (0)