Skip to content

Commit d5a0705

Browse files
docs(docs): align documentation with current implementation
1 parent 6b648cf commit d5a0705

25 files changed

Lines changed: 817 additions & 321 deletions

README.md

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010

1111
---
1212

13-
FastAPI extension that provides PASETO (**P**lastform-**A**gnostic **SE**curity **TO**kens) Auth support\
14-
PASETO are a simpler, yet more secure alternative to JWTs.
13+
FastAPI extension that provides PASETO (**P**latform-**A**gnostic **SE**curity **TO**kens) Auth support.
14+
PASETO tokens are a simpler, yet more secure alternative to JWTs.
1515

16-
If you were familiar with flask-jwt-extended or fastapi-jwt-auth this extension suitable for you, as this is forked from fastapi-jwt-auth which in turn used flask-jwt-extended as motivation
16+
If you are familiar with `flask-jwt-extended` or `fastapi-jwt-auth`, this
17+
extension should feel familiar. It is forked from `fastapi-jwt-auth`, which in
18+
turn was inspired by `flask-jwt-extended`.
1719

1820
## Features
1921
- Access tokens and refresh tokens
@@ -25,12 +27,18 @@ If you were familiar with flask-jwt-extended or fastapi-jwt-auth this extension
2527
- Custom token types
2628

2729
## Installation
28-
The easiest way to start working with this extension with pip
30+
31+
This project is not published on PyPI. Install it from an immutable Git tag or
32+
commit hash instead.
2933

3034
This project currently targets Python 3.14+.
3135

3236
```bash
33-
pip install fastapi-paseto
37+
uv add "fastapi-paseto @ git+https://github.com/Raze-Systems/fastapi-paseto.git@vX.Y.Z"
38+
```
39+
40+
```bash
41+
pip install "fastapi-paseto @ git+https://github.com/Raze-Systems/fastapi-paseto.git@vX.Y.Z"
3442
```
3543

3644
Releases are built from GitHub Actions after a successful semantic release on
@@ -48,12 +56,6 @@ def get_config():
4856
return {"authpaseto_secret_key": "secret"}
4957
```
5058

51-
## FAQ
52-
- **Where's support for tokens in cookies?**\
53-
This project focuses on header-based PASETO authentication and only includes the features required for that workflow.\
54-
Cookie storage is intentionally out of scope for now because it adds a large amount of behavior that does not fit the current design.\
55-
If there is strong demand and a solid implementation, contributions adding cookie support can still be considered.
56-
5759
## Release Process
5860
Releases are automated with conventional commits and semantic versioning.
5961
Commits merged into `main` should follow the Conventional Commits format, for
@@ -82,11 +84,14 @@ gh attestation verify ./fastapi_paseto-X.Y.Z-py3-none-any.whl --repo Raze-System
8284
gh attestation verify ./fastapi_paseto-X.Y.Z-py3-none-any.whl --repo Raze-Systems/fastapi-paseto --signer-workflow .github/workflows/release.yml --predicate-type https://spdx.dev/Document/v2.3
8385
```
8486

85-
If you install directly from Git, pin an immutable tag or commit hash instead
86-
of `main`:
87+
If you prefer to install from a commit hash instead of a release tag:
8788

8889
```bash
89-
pip install "fastapi-paseto @ git+https://github.com/Raze-Systems/fastapi-paseto.git@vX.Y.Z"
90+
uv add "fastapi-paseto @ git+https://github.com/Raze-Systems/fastapi-paseto.git@<commit-sha>"
91+
```
92+
93+
```bash
94+
pip install "fastapi-paseto @ git+https://github.com/Raze-Systems/fastapi-paseto.git@<commit-sha>"
9095
```
9196

9297
`pip` and `uv` record VCS origin metadata in `direct_url.json`, which helps
Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1-
You may want to store additional information in the access token or refresh token that you can later access in the protected views.
1+
You can store additional information in access, refresh, or custom tokens and
2+
read it later from protected endpoints.
3+
4+
Pass a dictionary through the `user_claims` parameter of
5+
`create_access_token()`, `create_refresh_token()`, or `create_token()`, then
6+
read it back with `get_token_payload()`.
7+
8+
Storing data in tokens can reduce repeated database lookups, but you still need
9+
to choose those claims carefully.
10+
11+
When using the `public` purpose, the token payload is signed but not encrypted.
12+
Anyone with the token can read its contents, so do not store sensitive
13+
information there. Whether `local` tokens are appropriate for sensitive data is
14+
still your own security decision.
215

3-
This can be done easily by passion additional information as a dictionary to the parameter **user_claims** in the functions **create_access_token()** or **create_refresh_token()**, and the data can be accessed later in a protected endpoint with the **get_token_payload()** function.
416

5-
Storing data in the tokens can be good for performance.\
6-
If you store data in the tokens, you won't need to look it up from disk/DB next time you need it in a protected endpoint.\
7-
However, you might need to take care of what data you put in the tokens.
8-
9-
**Note**: When using the "public" purpose of PASETO tokens, the data in the token will merely be signed, but not encrypted. This means anyone with access to the token can freely read it's contents.\
10-
Hence, do not store sensitive information in public tokens. Whether you trust local (encrypted) PASETO tokens to keep sensitive information is up to your own discretion.
11-
12-
13-
```python hl_lines="34-35 44"
14-
{!../examples/additional_claims.py!}
15-
```
17+
```python hl_lines="34-35 44"
18+
{!../examples/additional_claims.py!}
19+
```

docs/advanced-usage/bigger-app.md

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
Because *fastapi-paseto* configures your setting via a class state that applies across all instances of the class, you only need to make sure to call **load_config**(callback) before declaring any endpoint. Thanks to `FastAPI` when you make an endpoint from `APIRouter` it will actually work as if everything was the same single app.
2-
3-
So you only need to define **load_config**(callback) where your `FastAPI` instance is created or you can import it where you include all the routers.
1+
Because *fastapi-paseto* stores configuration on class state shared by all
2+
`AuthPASETO` instances, you only need to call `load_config()` once before your
3+
routes start handling requests.
4+
5+
In a larger FastAPI application, that usually means loading the config in the
6+
module that creates the main `FastAPI` app and then importing routers normally.
47

58
## An example file structure
69

@@ -17,19 +20,19 @@ Let's say you have a file structure like this:
1720
│ └── users.py
1821
```
1922

20-
Here an example of `app.py`
23+
Here is an example of `app.py`:
2124

2225
```python
2326
{!../examples/multiple_files/app.py!}
2427
```
2528

26-
Here an example of `users.py`
29+
Here is an example of `users.py`:
2730

2831
```python
2932
{!../examples/multiple_files/routers/users.py!}
3033
```
3134

32-
Here an example of `items.py`
35+
Here is an example of `items.py`:
3336

3437
```python
3538
{!../examples/multiple_files/routers/items.py!}

docs/advanced-usage/expiry_time.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,10 @@
1-
You can also change the expiry time for a token via parameter **expires_time** in the **create_access_token()** or **create_refresh_token()** function. This takes a *datetime.timedelta*, *datetime.datetime*, *integer*, or even *boolean* and overrides the `authpaseto_access_token_expires` and `authpaseto_refresh_token_expires` settings. This can be useful if you have different use cases for different tokens.
1+
You can override the default token lifetime with the `expires_time` parameter on
2+
`create_access_token()`, `create_refresh_token()`, or `create_token()`.
3+
4+
`expires_time` accepts a `datetime.timedelta`, `datetime.datetime`, integer
5+
seconds, or `False`. That override takes precedence over the configured
6+
`authpaseto_access_token_expires`, `authpaseto_refresh_token_expires`, or
7+
`authpaseto_other_token_expires` defaults.
28

39
```python
410
@app.post('/create-dynamic-token')
@@ -8,7 +14,7 @@ def create_dynamic_token(Authorize: AuthPASETO = Depends()):
814
return {"token": token}
915
```
1016

11-
You can even disable expiration by setting **expires_time** to *False*:
17+
You can disable expiration by setting `expires_time=False`:
1218

1319
```python
1420
@app.post('/create-token-disable')
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
It feels incomplete if there is no documentation because *fastapi-paseto* uses starlette requests directly to get headers, you must manually generate the documentation. Thanks to `FastAPI` you can generate doc easily via `Extending OpenAPI`.
1+
Because *fastapi-paseto* reads request data directly from Starlette request and
2+
websocket objects, FastAPI will not automatically describe those auth inputs in
3+
OpenAPI for you. If you want the generated docs to show the header or body
4+
contract, extend the OpenAPI schema manually.
5+
6+
Here is an example:
27

3-
Here is an example to generate the doc:
4-
5-
```python hl_lines="37 57-65 69 71-78"
6-
{!../examples/generate_doc.py!}
7-
```
8+
```python hl_lines="37 57-65 69 71-78"
9+
{!../examples/generate_doc.py!}
10+
```

docs/advanced-usage/overrides.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
`paseto_required()` can override the configured token transport on a single
2+
route. This is useful when most of your application follows one convention, but
3+
one endpoint needs a different header name, body key, prefix, or a token that
4+
was already extracted by another dependency.
5+
6+
The route-level override arguments are:
7+
8+
- `location`
9+
- `token_key`
10+
- `token_prefix`
11+
- `token`
12+
13+
```python hl_lines="37 44-48 55-60"
14+
{!../examples/overrides.py!}
15+
```
16+
17+
Notes:
18+
19+
- `location="json"` is only valid for HTTP requests.
20+
- `location="query"` is only valid for websocket handlers.
21+
- `token=` bypasses header, JSON, and query lookup entirely.
22+
- `token_prefix` can override the configured prefix with another non-empty
23+
string. If you need to disable the prefix completely, set the transport type
24+
to `None` in configuration.

docs/advanced-usage/purpose.md

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
1-
You can specify which purpose you would like to use for a PASETO by using the **purpose** parameter in **create_access_token()** or **create_refresh_token()**.
1+
You can choose the PASETO purpose used to create a token through the `purpose`
2+
parameter of `create_access_token()`, `create_refresh_token()`, or
3+
`create_token()`.
24

35
Please read up on PASETO tokens to find out which is the best purpose for your use case, but to put it short:
46

5-
**Local** purpose means the token will be encrypted using symmetric encryption. Data in the token will not be accessible to people that get the token without also knowing your secret key.\
6-
This is useful if the token is used in an environment where every party that needs access to the token's contents is a secure environment under your control that you can share the secret key with.
7+
**Local** means the token is encrypted with symmetric cryptography. Someone who
8+
obtains the token cannot read its contents without the shared secret key.
9+
This is a good fit when every party that needs to decrypt the token is under
10+
your control.
11+
12+
**Public** means the token is signed with your private key but not encrypted.
13+
The payload remains visible to anyone holding the token, so you should not put
14+
confidential data into public tokens. Public tokens can be verified with the
15+
matching public key, which is safe to share with untrusted parties.
716

8-
**Public** purpose means the token will not be encrypted, and instead will only be signed using your private key.
9-
The data in the key **will be visible to everyone that gets ahold of the key**, and you should not put any confidential or sensitive data into public keys.
10-
The key can then be validated using your public key, which is safe to share with not-trusted parties.
1117

12-
13-
```python hl_lines="16 35-36"
14-
{!../examples/purpose.py!}
15-
```
18+
```python hl_lines="16 35-36"
19+
{!../examples/purpose.py!}
20+
```

docs/advanced-usage/validation.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
FastAPI PASETO exposes validation controls for issuer, audience, custom token
2+
types, and base64-encoded tokens.
3+
4+
```python hl_lines="18-22 35-45 49 56 63"
5+
{!../examples/validation.py!}
6+
```
7+
8+
Use these options when you need stronger contracts than "any valid access token":
9+
10+
- Set `authpaseto_decode_issuer` to require an `iss` claim with a specific value.
11+
- Pass `audience=` when creating a token and set `authpaseto_decode_audience` to
12+
enforce the expected audience on decode.
13+
- Use `create_token(type="...")` together with `paseto_required(type="...")`
14+
for custom token flows such as email verification.
15+
- Use `base64_encode=True` when creating a token and
16+
`paseto_required(base64_encoded=True)` when validating it.
17+
18+
Important issuer detail:
19+
20+
- `authpaseto_encode_issuer` automatically adds `iss` only to
21+
`create_access_token()`.
22+
- `authpaseto_decode_issuer` applies to every decoded token.
23+
- If you enable issuer validation for refresh or custom tokens, those tokens
24+
must still include `iss`, typically through `user_claims`.

0 commit comments

Comments
 (0)