aegistry 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aegistry-0.1.0/.gitignore +12 -0
- aegistry-0.1.0/LICENSE +22 -0
- aegistry-0.1.0/PKG-INFO +171 -0
- aegistry-0.1.0/README.md +119 -0
- aegistry-0.1.0/aegistry/__init__.py +7 -0
- aegistry-0.1.0/aegistry/amr.py +102 -0
- aegistry-0.1.0/aegistry/authentication_session.py +334 -0
- aegistry-0.1.0/aegistry/contrib/__init__.py +0 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/__init__.py +37 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/config.py +120 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/cookies.py +83 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/dependencies.py +83 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/email_otp.py +193 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/flow.py +79 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/oauth2.py +324 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/password.py +240 -0
- aegistry-0.1.0/aegistry/contrib/fastapi/session.py +78 -0
- aegistry-0.1.0/aegistry/contrib/sqlalchemy/__init__.py +24 -0
- aegistry-0.1.0/aegistry/contrib/sqlalchemy/stores.py +369 -0
- aegistry-0.1.0/aegistry/contrib/sqlalchemy/tables.py +138 -0
- aegistry-0.1.0/aegistry/crypto.py +112 -0
- aegistry-0.1.0/aegistry/exceptions.py +9 -0
- aegistry-0.1.0/aegistry/factors/__init__.py +3 -0
- aegistry-0.1.0/aegistry/factors/backup_codes.py +216 -0
- aegistry-0.1.0/aegistry/factors/base.py +59 -0
- aegistry-0.1.0/aegistry/factors/email_otp.py +241 -0
- aegistry-0.1.0/aegistry/factors/hotp.py +343 -0
- aegistry-0.1.0/aegistry/factors/oauth2/__init__.py +0 -0
- aegistry-0.1.0/aegistry/factors/oauth2/apple.py +115 -0
- aegistry-0.1.0/aegistry/factors/oauth2/base.py +695 -0
- aegistry-0.1.0/aegistry/factors/oauth2/github.py +258 -0
- aegistry-0.1.0/aegistry/factors/oauth2/google.py +32 -0
- aegistry-0.1.0/aegistry/factors/oauth2/line.py +123 -0
- aegistry-0.1.0/aegistry/factors/oauth2/oidc.py +568 -0
- aegistry-0.1.0/aegistry/factors/oauth2/pkce.py +41 -0
- aegistry-0.1.0/aegistry/factors/oauth2/state.py +176 -0
- aegistry-0.1.0/aegistry/factors/password.py +228 -0
- aegistry-0.1.0/aegistry/factors/totp.py +345 -0
- aegistry-0.1.0/aegistry/logging.py +61 -0
- aegistry-0.1.0/aegistry/py.typed +0 -0
- aegistry-0.1.0/aegistry/session.py +257 -0
- aegistry-0.1.0/aegistry/timestamp.py +8 -0
- aegistry-0.1.0/pyproject.toml +75 -0
- aegistry-0.1.0/tests/__init__.py +0 -0
- aegistry-0.1.0/tests/conftest.py +14 -0
- aegistry-0.1.0/tests/contrib/__init__.py +0 -0
- aegistry-0.1.0/tests/contrib/test_fastapi_routers.py +785 -0
- aegistry-0.1.0/tests/contrib/test_sqlalchemy_stores.py +195 -0
- aegistry-0.1.0/tests/factors/__init__.py +0 -0
- aegistry-0.1.0/tests/factors/oauth2/__init__.py +0 -0
- aegistry-0.1.0/tests/factors/oauth2/conftest.py +119 -0
- aegistry-0.1.0/tests/factors/oauth2/test_base.py +478 -0
- aegistry-0.1.0/tests/factors/oauth2/test_line.py +218 -0
- aegistry-0.1.0/tests/factors/oauth2/test_oidc.py +590 -0
- aegistry-0.1.0/tests/factors/oauth2/test_pkce.py +40 -0
- aegistry-0.1.0/tests/factors/oauth2/test_state.py +193 -0
- aegistry-0.1.0/tests/factors/test_backup_codes.py +269 -0
- aegistry-0.1.0/tests/factors/test_email_otp.py +277 -0
- aegistry-0.1.0/tests/factors/test_hotp.py +280 -0
- aegistry-0.1.0/tests/factors/test_password.py +110 -0
- aegistry-0.1.0/tests/factors/test_totp.py +344 -0
- aegistry-0.1.0/tests/test_authentication_session.py +474 -0
- aegistry-0.1.0/tests/test_crypto.py +158 -0
- aegistry-0.1.0/tests/test_session.py +145 -0
aegistry-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, François Voron
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
aegistry-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: aegistry
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Batteries-included authentication toolkit for FastAPI — a friendly fork of reauth
|
|
5
|
+
Project-URL: Source, https://github.com/primemeridiem/aegistry
|
|
6
|
+
Author: aegistry
|
|
7
|
+
License: MIT License
|
|
8
|
+
|
|
9
|
+
Copyright (c) 2026, François Voron
|
|
10
|
+
|
|
11
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
12
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
13
|
+
in the Software without restriction, including without limitation the rights
|
|
14
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
15
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
16
|
+
furnished to do so, subject to the following conditions:
|
|
17
|
+
|
|
18
|
+
The above copyright notice and this permission notice shall be included in all
|
|
19
|
+
copies or substantial portions of the Software.
|
|
20
|
+
|
|
21
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
22
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
23
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
24
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
25
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
26
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
27
|
+
SOFTWARE.
|
|
28
|
+
|
|
29
|
+
License-File: LICENSE
|
|
30
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
31
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
32
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
33
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
34
|
+
Requires-Python: >=3.12
|
|
35
|
+
Requires-Dist: anyio
|
|
36
|
+
Requires-Dist: cryptography<49.0.0,>=48.0.0
|
|
37
|
+
Requires-Dist: httpx>=0.28.1
|
|
38
|
+
Requires-Dist: pyjwt>=2.12.1
|
|
39
|
+
Provides-Extra: all
|
|
40
|
+
Requires-Dist: email-validator>=2.0; extra == 'all'
|
|
41
|
+
Requires-Dist: fastapi>=0.115.0; extra == 'all'
|
|
42
|
+
Requires-Dist: pwdlib[argon2]>=0.2.1; extra == 'all'
|
|
43
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.30; extra == 'all'
|
|
44
|
+
Provides-Extra: fastapi
|
|
45
|
+
Requires-Dist: email-validator>=2.0; extra == 'fastapi'
|
|
46
|
+
Requires-Dist: fastapi>=0.115.0; extra == 'fastapi'
|
|
47
|
+
Provides-Extra: password
|
|
48
|
+
Requires-Dist: pwdlib[argon2]>=0.2.1; extra == 'password'
|
|
49
|
+
Provides-Extra: sqlalchemy
|
|
50
|
+
Requires-Dist: sqlalchemy[asyncio]>=2.0.30; extra == 'sqlalchemy'
|
|
51
|
+
Description-Content-Type: text/markdown
|
|
52
|
+
|
|
53
|
+
# Aegistry
|
|
54
|
+
|
|
55
|
+
<p align="center">
|
|
56
|
+
<em>Batteries-included authentication for FastAPI</em>
|
|
57
|
+
</p>
|
|
58
|
+
|
|
59
|
+
Aegistry is an authentication toolkit for Python with first-class FastAPI
|
|
60
|
+
integration: Email/Password, Email OTP, Google Sign-In, LINE Login, MFA
|
|
61
|
+
(TOTP, backup codes), and session management — on Python 3.12+.
|
|
62
|
+
|
|
63
|
+
> [!NOTE]
|
|
64
|
+
> Aegistry's core is a friendly fork of [reauth](https://github.com/frankie567/reauth)
|
|
65
|
+
> 0.1.8 (MIT, © 2026 François Voron), backported to Python 3.12. Aegistry adds the
|
|
66
|
+
> integration layers reauth doesn't ship yet: password & LINE factors, post-login
|
|
67
|
+
> session management, SQLAlchemy stores, and ready-made FastAPI routers. We aim to
|
|
68
|
+
> stay architecturally compatible with reauth and upstream what makes sense.
|
|
69
|
+
|
|
70
|
+
## Architecture
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
aegistry/
|
|
74
|
+
├── crypto.py # opaque tokens + HMAC-SHA256 hash pairs
|
|
75
|
+
├── amr.py # RFC 8176 Authentication Method References
|
|
76
|
+
├── authentication_session.py # pre-login MFA state machine (steps, AMR)
|
|
77
|
+
├── session.py # post-login sessions (sliding expiration)
|
|
78
|
+
├── factors/
|
|
79
|
+
│ ├── password.py # argon2id via pwdlib [aegistry]
|
|
80
|
+
│ ├── email_otp.py # one-time codes by email
|
|
81
|
+
│ ├── totp.py / hotp.py / backup_codes.py
|
|
82
|
+
│ └── oauth2/
|
|
83
|
+
│ ├── base.py # OAuth2 authorization code + PKCE
|
|
84
|
+
│ ├── oidc.py # discovery, JWKS, id_token validation
|
|
85
|
+
│ ├── google.py / github.py / apple.py
|
|
86
|
+
│ └── line.py # LINE Login v2.1 [aegistry]
|
|
87
|
+
└── contrib/
|
|
88
|
+
├── sqlalchemy/ # ready-made async stores [aegistry]
|
|
89
|
+
└── fastapi/ # routers, dependencies, cookies [aegistry]
|
|
90
|
+
|
|
91
|
+
clients/ # TypeScript SDK (pnpm workspace) [aegistry]
|
|
92
|
+
├── packages/client # @aegistry/client — core, getServerSession
|
|
93
|
+
└── packages/react # @aegistry/react — useSession()
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
For the Next.js/React side, see [clients/README.md](clients/README.md).
|
|
97
|
+
|
|
98
|
+
Design principles (inherited from reauth, shared with Better Auth):
|
|
99
|
+
|
|
100
|
+
- **Framework-agnostic core.** Factors and services are plain async Python with
|
|
101
|
+
abstract persistence methods. `contrib/` packages depend on the core — never
|
|
102
|
+
the reverse.
|
|
103
|
+
- **Tokens are opaque, prefixed, and stored hashed.** Only HMAC-SHA256 hashes
|
|
104
|
+
hit the database.
|
|
105
|
+
- **MFA by construction.** Login is an *authentication session* that factors
|
|
106
|
+
advance step by step; it completes only when no required factor remains.
|
|
107
|
+
- **PKCE + state + nonce** on every OAuth2/OIDC flow.
|
|
108
|
+
|
|
109
|
+
## Installation
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
pip install "aegistry[all]" # everything
|
|
113
|
+
pip install "aegistry[fastapi,sqlalchemy,password]"
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Quickstart (FastAPI + SQLAlchemy)
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from aegistry.contrib.fastapi import AuthConfig, get_password_router, get_oauth2_login_router
|
|
120
|
+
from aegistry.contrib.sqlalchemy import create_tables
|
|
121
|
+
|
|
122
|
+
config = AuthConfig(success_redirect_url="/app")
|
|
123
|
+
tables = create_tables(metadata) # or define your own tables/stores
|
|
124
|
+
|
|
125
|
+
app.include_router(
|
|
126
|
+
get_password_router(
|
|
127
|
+
factor_dependency=get_password_factor,
|
|
128
|
+
authentication_session_service_dependency=get_authentication_session_service,
|
|
129
|
+
session_service_dependency=get_session_service,
|
|
130
|
+
identity_resolver_dependency=get_identity_resolver,
|
|
131
|
+
config=config,
|
|
132
|
+
),
|
|
133
|
+
prefix="/auth",
|
|
134
|
+
)
|
|
135
|
+
app.include_router(
|
|
136
|
+
get_oauth2_login_router(
|
|
137
|
+
identifier="google",
|
|
138
|
+
factor_dependency=get_google_factor,
|
|
139
|
+
authentication_session_service_dependency=get_authentication_session_service,
|
|
140
|
+
session_service_dependency=get_session_service,
|
|
141
|
+
identity_resolver_dependency=get_identity_resolver,
|
|
142
|
+
scope=["openid", "email", "profile"],
|
|
143
|
+
config=config,
|
|
144
|
+
),
|
|
145
|
+
prefix="/auth",
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Your app provides the *dependencies* (wired to your database session) and an
|
|
150
|
+
``IdentityResolver`` mapping verified emails to your user rows; aegistry
|
|
151
|
+
provides the flows. See ``tests/contrib/test_fastapi_routers.py`` for a
|
|
152
|
+
complete, runnable wiring.
|
|
153
|
+
|
|
154
|
+
### Provider notes
|
|
155
|
+
|
|
156
|
+
- **Google** — pure OIDC; `GoogleOAuth2Factor` validates id_tokens against
|
|
157
|
+
Google's JWKS. Email arrives with `email_verified`.
|
|
158
|
+
- **LINE** — `LineOAuth2Factor` validates id_tokens through LINE's verify
|
|
159
|
+
endpoint (web-login tokens are HS256-signed with the channel secret, so
|
|
160
|
+
JWKS validation can't be used). The `email` scope requires applying for
|
|
161
|
+
permission in the LINE Developers console, and LINE never returns
|
|
162
|
+
`email_verified` — don't auto-link LINE accounts to existing users by
|
|
163
|
+
email without an extra verification step.
|
|
164
|
+
|
|
165
|
+
## Status
|
|
166
|
+
|
|
167
|
+
Early scaffold — APIs unstable. See upstream reauth for the core roadmap.
|
|
168
|
+
|
|
169
|
+
## License
|
|
170
|
+
|
|
171
|
+
MIT. Contains code from reauth, © 2026 François Voron, MIT licensed.
|
aegistry-0.1.0/README.md
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
# Aegistry
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<em>Batteries-included authentication for FastAPI</em>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
Aegistry is an authentication toolkit for Python with first-class FastAPI
|
|
8
|
+
integration: Email/Password, Email OTP, Google Sign-In, LINE Login, MFA
|
|
9
|
+
(TOTP, backup codes), and session management — on Python 3.12+.
|
|
10
|
+
|
|
11
|
+
> [!NOTE]
|
|
12
|
+
> Aegistry's core is a friendly fork of [reauth](https://github.com/frankie567/reauth)
|
|
13
|
+
> 0.1.8 (MIT, © 2026 François Voron), backported to Python 3.12. Aegistry adds the
|
|
14
|
+
> integration layers reauth doesn't ship yet: password & LINE factors, post-login
|
|
15
|
+
> session management, SQLAlchemy stores, and ready-made FastAPI routers. We aim to
|
|
16
|
+
> stay architecturally compatible with reauth and upstream what makes sense.
|
|
17
|
+
|
|
18
|
+
## Architecture
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
aegistry/
|
|
22
|
+
├── crypto.py # opaque tokens + HMAC-SHA256 hash pairs
|
|
23
|
+
├── amr.py # RFC 8176 Authentication Method References
|
|
24
|
+
├── authentication_session.py # pre-login MFA state machine (steps, AMR)
|
|
25
|
+
├── session.py # post-login sessions (sliding expiration)
|
|
26
|
+
├── factors/
|
|
27
|
+
│ ├── password.py # argon2id via pwdlib [aegistry]
|
|
28
|
+
│ ├── email_otp.py # one-time codes by email
|
|
29
|
+
│ ├── totp.py / hotp.py / backup_codes.py
|
|
30
|
+
│ └── oauth2/
|
|
31
|
+
│ ├── base.py # OAuth2 authorization code + PKCE
|
|
32
|
+
│ ├── oidc.py # discovery, JWKS, id_token validation
|
|
33
|
+
│ ├── google.py / github.py / apple.py
|
|
34
|
+
│ └── line.py # LINE Login v2.1 [aegistry]
|
|
35
|
+
└── contrib/
|
|
36
|
+
├── sqlalchemy/ # ready-made async stores [aegistry]
|
|
37
|
+
└── fastapi/ # routers, dependencies, cookies [aegistry]
|
|
38
|
+
|
|
39
|
+
clients/ # TypeScript SDK (pnpm workspace) [aegistry]
|
|
40
|
+
├── packages/client # @aegistry/client — core, getServerSession
|
|
41
|
+
└── packages/react # @aegistry/react — useSession()
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
For the Next.js/React side, see [clients/README.md](clients/README.md).
|
|
45
|
+
|
|
46
|
+
Design principles (inherited from reauth, shared with Better Auth):
|
|
47
|
+
|
|
48
|
+
- **Framework-agnostic core.** Factors and services are plain async Python with
|
|
49
|
+
abstract persistence methods. `contrib/` packages depend on the core — never
|
|
50
|
+
the reverse.
|
|
51
|
+
- **Tokens are opaque, prefixed, and stored hashed.** Only HMAC-SHA256 hashes
|
|
52
|
+
hit the database.
|
|
53
|
+
- **MFA by construction.** Login is an *authentication session* that factors
|
|
54
|
+
advance step by step; it completes only when no required factor remains.
|
|
55
|
+
- **PKCE + state + nonce** on every OAuth2/OIDC flow.
|
|
56
|
+
|
|
57
|
+
## Installation
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install "aegistry[all]" # everything
|
|
61
|
+
pip install "aegistry[fastapi,sqlalchemy,password]"
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Quickstart (FastAPI + SQLAlchemy)
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
from aegistry.contrib.fastapi import AuthConfig, get_password_router, get_oauth2_login_router
|
|
68
|
+
from aegistry.contrib.sqlalchemy import create_tables
|
|
69
|
+
|
|
70
|
+
config = AuthConfig(success_redirect_url="/app")
|
|
71
|
+
tables = create_tables(metadata) # or define your own tables/stores
|
|
72
|
+
|
|
73
|
+
app.include_router(
|
|
74
|
+
get_password_router(
|
|
75
|
+
factor_dependency=get_password_factor,
|
|
76
|
+
authentication_session_service_dependency=get_authentication_session_service,
|
|
77
|
+
session_service_dependency=get_session_service,
|
|
78
|
+
identity_resolver_dependency=get_identity_resolver,
|
|
79
|
+
config=config,
|
|
80
|
+
),
|
|
81
|
+
prefix="/auth",
|
|
82
|
+
)
|
|
83
|
+
app.include_router(
|
|
84
|
+
get_oauth2_login_router(
|
|
85
|
+
identifier="google",
|
|
86
|
+
factor_dependency=get_google_factor,
|
|
87
|
+
authentication_session_service_dependency=get_authentication_session_service,
|
|
88
|
+
session_service_dependency=get_session_service,
|
|
89
|
+
identity_resolver_dependency=get_identity_resolver,
|
|
90
|
+
scope=["openid", "email", "profile"],
|
|
91
|
+
config=config,
|
|
92
|
+
),
|
|
93
|
+
prefix="/auth",
|
|
94
|
+
)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Your app provides the *dependencies* (wired to your database session) and an
|
|
98
|
+
``IdentityResolver`` mapping verified emails to your user rows; aegistry
|
|
99
|
+
provides the flows. See ``tests/contrib/test_fastapi_routers.py`` for a
|
|
100
|
+
complete, runnable wiring.
|
|
101
|
+
|
|
102
|
+
### Provider notes
|
|
103
|
+
|
|
104
|
+
- **Google** — pure OIDC; `GoogleOAuth2Factor` validates id_tokens against
|
|
105
|
+
Google's JWKS. Email arrives with `email_verified`.
|
|
106
|
+
- **LINE** — `LineOAuth2Factor` validates id_tokens through LINE's verify
|
|
107
|
+
endpoint (web-login tokens are HS256-signed with the channel secret, so
|
|
108
|
+
JWKS validation can't be used). The `email` scope requires applying for
|
|
109
|
+
permission in the LINE Developers console, and LINE never returns
|
|
110
|
+
`email_verified` — don't auto-link LINE accounts to existing users by
|
|
111
|
+
email without an extra verification step.
|
|
112
|
+
|
|
113
|
+
## Status
|
|
114
|
+
|
|
115
|
+
Early scaffold — APIs unstable. See upstream reauth for the core roadmap.
|
|
116
|
+
|
|
117
|
+
## License
|
|
118
|
+
|
|
119
|
+
MIT. Contains code from reauth, © 2026 François Voron, MIT licensed.
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""Authentication Method Reference Values (amr) per RFC 8176.
|
|
2
|
+
|
|
3
|
+
This module defines the standard Authentication Method Reference values
|
|
4
|
+
as specified in RFC 8176 for use in JWT amr claims. These values represent
|
|
5
|
+
the authentication methods used in an authentication event.
|
|
6
|
+
|
|
7
|
+
See: https://datatracker.ietf.org/doc/html/rfc8176
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from enum import StrEnum
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class AuthenticationMethodReference(StrEnum):
|
|
14
|
+
"""Standard Authentication Method Reference values (amr) per RFC 8176.
|
|
15
|
+
|
|
16
|
+
These values are used in the 'amr' claim of JSON Web Tokens (JWT) to
|
|
17
|
+
identify the authentication methods used in an authentication event.
|
|
18
|
+
|
|
19
|
+
Each value represents a family of closely related authentication methods.
|
|
20
|
+
The registry is maintained by IANA and is extensible.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
# Biometric methods
|
|
24
|
+
FACE = "face"
|
|
25
|
+
"""Facial recognition biometric authentication."""
|
|
26
|
+
|
|
27
|
+
FPT = "fpt"
|
|
28
|
+
"""Fingerprint biometric authentication."""
|
|
29
|
+
|
|
30
|
+
IRIS = "iris"
|
|
31
|
+
"""Iris scan biometric authentication."""
|
|
32
|
+
|
|
33
|
+
RETINA = "retina"
|
|
34
|
+
"""Retina scan biometric authentication."""
|
|
35
|
+
|
|
36
|
+
VBM = "vbm"
|
|
37
|
+
"""Voice biometric authentication."""
|
|
38
|
+
|
|
39
|
+
# Knowledge-based methods
|
|
40
|
+
KBA = "kba"
|
|
41
|
+
"""Knowledge-based authentication (e.g., security questions)."""
|
|
42
|
+
|
|
43
|
+
PIN = "pin"
|
|
44
|
+
"""Personal Identification Number or pattern authentication."""
|
|
45
|
+
|
|
46
|
+
PWD = "pwd"
|
|
47
|
+
"""Password-based authentication."""
|
|
48
|
+
|
|
49
|
+
# Possession-based methods
|
|
50
|
+
HWK = "hwk"
|
|
51
|
+
"""Proof-of-Possession of a hardware-secured key."""
|
|
52
|
+
|
|
53
|
+
OTP = "otp"
|
|
54
|
+
"""One-time password (HOTP/TOTP)."""
|
|
55
|
+
|
|
56
|
+
SC = "sc"
|
|
57
|
+
"""Smart card authentication."""
|
|
58
|
+
|
|
59
|
+
SWK = "swk"
|
|
60
|
+
"""Proof-of-Possession of a software-secured key."""
|
|
61
|
+
|
|
62
|
+
# Out-of-band methods
|
|
63
|
+
SMS = "sms"
|
|
64
|
+
"""SMS text message confirmation."""
|
|
65
|
+
|
|
66
|
+
TEL = "tel"
|
|
67
|
+
"""Telephone call confirmation."""
|
|
68
|
+
|
|
69
|
+
EMAIL = "email"
|
|
70
|
+
"""Email-based OTP or magic link authentication.
|
|
71
|
+
|
|
72
|
+
This is a custom extension to RFC 8176, not part of the standard.
|
|
73
|
+
"""
|
|
74
|
+
|
|
75
|
+
OAUTH2 = "oauth2"
|
|
76
|
+
"""OAuth 2.0 authentication, including social login.
|
|
77
|
+
|
|
78
|
+
This is a custom extension to RFC 8176, not part of the standard.
|
|
79
|
+
"""
|
|
80
|
+
|
|
81
|
+
# Multi-factor and risk-based methods
|
|
82
|
+
MFA = "mfa"
|
|
83
|
+
"""Multiple-factor authentication."""
|
|
84
|
+
|
|
85
|
+
MCA = "mca"
|
|
86
|
+
"""Multiple-channel authentication."""
|
|
87
|
+
|
|
88
|
+
RBA = "rba"
|
|
89
|
+
"""Risk-based authentication."""
|
|
90
|
+
|
|
91
|
+
# Special purpose
|
|
92
|
+
GEO = "geo"
|
|
93
|
+
"""Geolocation-based authentication."""
|
|
94
|
+
|
|
95
|
+
USER = "user"
|
|
96
|
+
"""User presence test."""
|
|
97
|
+
|
|
98
|
+
WIA = "wia"
|
|
99
|
+
"""Windows Integrated Authentication."""
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
__all__ = ["AuthenticationMethodReference"]
|