diff --git a/backend/src/auth/claims.rs b/backend/src/auth/claims.rs new file mode 100644 index 0000000..2bdf5cc --- /dev/null +++ b/backend/src/auth/claims.rs @@ -0,0 +1,22 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct AccessClaims { + pub sub: String, + pub email: String, + pub family_id: Option, + pub permissions: Vec, + pub token_type: String, + pub iat: i64, + pub exp: i64, + pub jti: String, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct RefreshClaims { + pub sub: String, + pub token_type: String, + pub iat: i64, + pub exp: i64, + pub jti: String, +} diff --git a/docs/adr/jwt-authentication-decision.md b/docs/adr/jwt-authentication-decision.md index 8af389d..b8d2190 100644 --- a/docs/adr/jwt-authentication-decision.md +++ b/docs/adr/jwt-authentication-decision.md @@ -65,10 +65,10 @@ Note what is **absent** and why: enforcement is not implemented at the auth layer (see issue #3 — multi-person sharing is an open design problem). Putting unenforced claims in the token would imply protection that doesn't exist. - - (Historical: an orphaned `backend/src/auth/claims.rs` once defined a - duplicate `AccessClaims` struct with `family_id`/`permissions`/`jti`. It - was dead code — never declared as a module, never imported — and has been - removed; see issue #5.) + - `backend/src/auth/claims.rs` *does* define an `AccessClaims` struct with + `family_id`, `permissions`, `token_type`, `jti`. **It is dead code** — not + imported or used anywhere in the source (only in stale compiler scratch + files under `target/`). It should be removed or wired up; tracked by issue #4. - **No `token_type` discriminator.** Access and refresh claims are different structs, so a token can only decode as one or the other — the field is redundant and was dropped. @@ -151,13 +151,13 @@ never on the server to protect: - HS256 with a shared secret means the secret is sensitive infrastructure; a key rotation requires invalidating all tokens (acceptable for the deployment model, but worth noting vs. asymmetric RS/ES keys). +- The dead `AccessClaims` struct is a latent trap — someone could wire it up + assuming `family_id`/`permissions` are enforced. Should be deleted. ## Open items -- ~~Remove `backend/src/auth/claims.rs` (dead `AccessClaims`) or wire it up - intentionally.~~ **Done** — the orphaned file has been deleted (issue #5, - PR #). The live `Claims` / `RefreshClaims` structs in - `backend/src/auth/jwt.rs` are the only ones. +- **Remove `backend/src/auth/claims.rs`** (dead `AccessClaims`) or wire it up + intentionally. Tracked under issue #4. - When issue #3 (multi-person sharing) is decided, revisit whether family / share authorization belongs in the JWT or is enforced per-request against a shares collection.