feat: JWT auth validation with Authentik OIDC

- Add jwt_validator module with JWKS caching (TTL + refresh-on-miss)
- Implement RS256 algorithm pinning + claim validation
- Replace apikey with Bearer token validation in http_server
- Add capability-based access control (memory:read/write/*)
- Backward compatible: MEM_AUTH_MODE=jwt|apikey (default: apikey)
- 16 tests passing (7 unit + 9 integration)
- Docs: JWT_AUTH.md with deployment guide

Config via env vars:
- MEM_AUTH_MODE=jwt
- AUTHENTIK_ISSUER=https://authentik.riotpiao.com/application/o/poimen-memory/
- AUTHENTIK_AUDIENCE=poimen-memory
- JWT_CACHE_TTL_SECS=3600 (optional)

Gw passes Authorization: Bearer <token> header
Memory validates + checks permissions claim
This commit is contained in:
Story Crater Bot
2026-08-27 12:29:23 -07:00
parent 82cc2c8310
commit 47e55afae3
9 changed files with 997 additions and 45 deletions
Generated
+84 -13
View File
@@ -505,7 +505,7 @@ dependencies = [
"sha2 0.10.9",
"tar",
"tempfile",
"thiserror",
"thiserror 1.0.69",
"zip",
]
@@ -1259,8 +1259,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.1+wasi-snapshot-preview1",
"wasm-bindgen",
]
[[package]]
@@ -1808,6 +1810,21 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonwebtoken"
version = "9.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde"
dependencies = [
"base64 0.22.1",
"js-sys",
"pem",
"ring",
"serde",
"serde_json",
"simple_asn1",
]
[[package]]
name = "language-tags"
version = "0.3.2"
@@ -1950,7 +1967,7 @@ dependencies = [
"serde",
"serde_json",
"sha2 0.10.9",
"thiserror",
"thiserror 1.0.69",
"time",
"tokenizers",
"tokio",
@@ -1968,18 +1985,20 @@ dependencies = [
"chrono",
"clap",
"futures",
"jsonwebtoken",
"mem-chunk",
"mem-core",
"mem-ingest",
"mem-llm",
"mem-store",
"pgvector",
"reqwest",
"serde",
"serde_json",
"serde_yaml",
"sha2 0.10.9",
"sqlx",
"thiserror",
"thiserror 1.0.69",
"time",
"tokio",
"tracing",
@@ -1998,7 +2017,7 @@ dependencies = [
"serde_json",
"serde_yaml",
"sha2 0.10.9",
"thiserror",
"thiserror 1.0.69",
"time",
"tokio",
"tracing",
@@ -2016,7 +2035,7 @@ dependencies = [
"serde_json",
"serde_yaml",
"sha2 0.10.9",
"thiserror",
"thiserror 1.0.69",
"time",
"tokio",
"tracing",
@@ -2035,7 +2054,7 @@ dependencies = [
"reqwest",
"serde",
"serde_json",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tracing",
"uuid",
@@ -2052,7 +2071,7 @@ dependencies = [
"serde",
"serde_json",
"sqlx",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tracing",
"uuid",
@@ -2156,6 +2175,16 @@ dependencies = [
"windows-sys 0.61.2",
]
[[package]]
name = "num-bigint"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c89e69e7e0f03bea5ef08013795c25018e101932225a656383bd384495ecc367"
dependencies = [
"num-integer",
"num-traits",
]
[[package]]
name = "num-bigint-dig"
version = "0.8.6"
@@ -2376,6 +2405,16 @@ dependencies = [
"sha2 0.10.9",
]
[[package]]
name = "pem"
version = "3.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d30c53c26bc5b31a98cd02d20f25a7c8567146caf63ed593a9d87b2775291be"
dependencies = [
"base64 0.22.1",
"serde_core",
]
[[package]]
name = "pem-rfc7468"
version = "0.7.0"
@@ -2684,7 +2723,7 @@ checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43"
dependencies = [
"getrandom 0.2.17",
"libredox",
"thiserror",
"thiserror 1.0.69",
]
[[package]]
@@ -3091,6 +3130,18 @@ version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3a219298ac11a56ea9a6d2120044824d6f01aeb034955e7af7bc16858527deea"
[[package]]
name = "simple_asn1"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d585997b0ac10be3c5ee635f1bab02d512760d14b7c468801ac8a01d9ae5f1d"
dependencies = [
"num-bigint",
"num-traits",
"thiserror 2.0.20",
"time",
]
[[package]]
name = "siphasher"
version = "1.0.3"
@@ -3218,7 +3269,7 @@ dependencies = [
"sha2 0.10.9",
"smallvec",
"sqlformat",
"thiserror",
"thiserror 1.0.69",
"tokio",
"tokio-stream",
"tracing",
@@ -3304,7 +3355,7 @@ dependencies = [
"smallvec",
"sqlx-core",
"stringprep",
"thiserror",
"thiserror 1.0.69",
"tracing",
"uuid",
"whoami 1.6.1",
@@ -3344,7 +3395,7 @@ dependencies = [
"smallvec",
"sqlx-core",
"stringprep",
"thiserror",
"thiserror 1.0.69",
"tracing",
"uuid",
"whoami 1.6.1",
@@ -3511,7 +3562,16 @@ version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl",
"thiserror-impl 1.0.69",
]
[[package]]
name = "thiserror"
version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec86235f5fcc2a73650310756d2ac5b138a5780bbbdfae3eeccec992c435ba4f"
dependencies = [
"thiserror-impl 2.0.20",
]
[[package]]
@@ -3525,6 +3585,17 @@ dependencies = [
"syn 2.0.119",
]
[[package]]
name = "thiserror-impl"
version = "2.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc04cd3e1236dd4a98afca4569f2deb3f120e5422a4023be2cb683f8486292af"
dependencies = [
"proc-macro2",
"quote",
"syn 3.0.4",
]
[[package]]
name = "thread_local"
version = "1.1.10"
@@ -3619,7 +3690,7 @@ dependencies = [
"serde",
"serde_json",
"spm_precompiled",
"thiserror",
"thiserror 1.0.69",
"unicode-normalization-alignments",
"unicode-segmentation",
"unicode_categories",