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.
Files changed (64) hide show
  1. aegistry-0.1.0/.gitignore +12 -0
  2. aegistry-0.1.0/LICENSE +22 -0
  3. aegistry-0.1.0/PKG-INFO +171 -0
  4. aegistry-0.1.0/README.md +119 -0
  5. aegistry-0.1.0/aegistry/__init__.py +7 -0
  6. aegistry-0.1.0/aegistry/amr.py +102 -0
  7. aegistry-0.1.0/aegistry/authentication_session.py +334 -0
  8. aegistry-0.1.0/aegistry/contrib/__init__.py +0 -0
  9. aegistry-0.1.0/aegistry/contrib/fastapi/__init__.py +37 -0
  10. aegistry-0.1.0/aegistry/contrib/fastapi/config.py +120 -0
  11. aegistry-0.1.0/aegistry/contrib/fastapi/cookies.py +83 -0
  12. aegistry-0.1.0/aegistry/contrib/fastapi/dependencies.py +83 -0
  13. aegistry-0.1.0/aegistry/contrib/fastapi/email_otp.py +193 -0
  14. aegistry-0.1.0/aegistry/contrib/fastapi/flow.py +79 -0
  15. aegistry-0.1.0/aegistry/contrib/fastapi/oauth2.py +324 -0
  16. aegistry-0.1.0/aegistry/contrib/fastapi/password.py +240 -0
  17. aegistry-0.1.0/aegistry/contrib/fastapi/session.py +78 -0
  18. aegistry-0.1.0/aegistry/contrib/sqlalchemy/__init__.py +24 -0
  19. aegistry-0.1.0/aegistry/contrib/sqlalchemy/stores.py +369 -0
  20. aegistry-0.1.0/aegistry/contrib/sqlalchemy/tables.py +138 -0
  21. aegistry-0.1.0/aegistry/crypto.py +112 -0
  22. aegistry-0.1.0/aegistry/exceptions.py +9 -0
  23. aegistry-0.1.0/aegistry/factors/__init__.py +3 -0
  24. aegistry-0.1.0/aegistry/factors/backup_codes.py +216 -0
  25. aegistry-0.1.0/aegistry/factors/base.py +59 -0
  26. aegistry-0.1.0/aegistry/factors/email_otp.py +241 -0
  27. aegistry-0.1.0/aegistry/factors/hotp.py +343 -0
  28. aegistry-0.1.0/aegistry/factors/oauth2/__init__.py +0 -0
  29. aegistry-0.1.0/aegistry/factors/oauth2/apple.py +115 -0
  30. aegistry-0.1.0/aegistry/factors/oauth2/base.py +695 -0
  31. aegistry-0.1.0/aegistry/factors/oauth2/github.py +258 -0
  32. aegistry-0.1.0/aegistry/factors/oauth2/google.py +32 -0
  33. aegistry-0.1.0/aegistry/factors/oauth2/line.py +123 -0
  34. aegistry-0.1.0/aegistry/factors/oauth2/oidc.py +568 -0
  35. aegistry-0.1.0/aegistry/factors/oauth2/pkce.py +41 -0
  36. aegistry-0.1.0/aegistry/factors/oauth2/state.py +176 -0
  37. aegistry-0.1.0/aegistry/factors/password.py +228 -0
  38. aegistry-0.1.0/aegistry/factors/totp.py +345 -0
  39. aegistry-0.1.0/aegistry/logging.py +61 -0
  40. aegistry-0.1.0/aegistry/py.typed +0 -0
  41. aegistry-0.1.0/aegistry/session.py +257 -0
  42. aegistry-0.1.0/aegistry/timestamp.py +8 -0
  43. aegistry-0.1.0/pyproject.toml +75 -0
  44. aegistry-0.1.0/tests/__init__.py +0 -0
  45. aegistry-0.1.0/tests/conftest.py +14 -0
  46. aegistry-0.1.0/tests/contrib/__init__.py +0 -0
  47. aegistry-0.1.0/tests/contrib/test_fastapi_routers.py +785 -0
  48. aegistry-0.1.0/tests/contrib/test_sqlalchemy_stores.py +195 -0
  49. aegistry-0.1.0/tests/factors/__init__.py +0 -0
  50. aegistry-0.1.0/tests/factors/oauth2/__init__.py +0 -0
  51. aegistry-0.1.0/tests/factors/oauth2/conftest.py +119 -0
  52. aegistry-0.1.0/tests/factors/oauth2/test_base.py +478 -0
  53. aegistry-0.1.0/tests/factors/oauth2/test_line.py +218 -0
  54. aegistry-0.1.0/tests/factors/oauth2/test_oidc.py +590 -0
  55. aegistry-0.1.0/tests/factors/oauth2/test_pkce.py +40 -0
  56. aegistry-0.1.0/tests/factors/oauth2/test_state.py +193 -0
  57. aegistry-0.1.0/tests/factors/test_backup_codes.py +269 -0
  58. aegistry-0.1.0/tests/factors/test_email_otp.py +277 -0
  59. aegistry-0.1.0/tests/factors/test_hotp.py +280 -0
  60. aegistry-0.1.0/tests/factors/test_password.py +110 -0
  61. aegistry-0.1.0/tests/factors/test_totp.py +344 -0
  62. aegistry-0.1.0/tests/test_authentication_session.py +474 -0
  63. aegistry-0.1.0/tests/test_crypto.py +158 -0
  64. aegistry-0.1.0/tests/test_session.py +145 -0
@@ -0,0 +1,12 @@
1
+ __pycache__/
2
+ *.pyc
3
+ .venv/
4
+ dist/
5
+ .coverage
6
+ .pytest_cache/
7
+ .ruff_cache/
8
+ node_modules/
9
+ clients/packages/*/dist/
10
+ .next/
11
+ demo.db
12
+ .env
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
+
@@ -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.
@@ -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,7 @@
1
+ """The authentication toolkit for Python"""
2
+
3
+ from aegistry.logging import configure_logger, get_logger
4
+
5
+ __version__ = "0.1.0"
6
+
7
+ __all__ = ["__version__", "configure_logger", "get_logger"]
@@ -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"]