|
| 1 | +--- |
| 2 | +status: 'proposed' |
| 3 | +date: '2025-10-07' |
| 4 | +tags: |
| 5 | + - authorization |
| 6 | +driver: '@jakedoublev' |
| 7 | +consulted: |
| 8 | + - '@jrschumacher' |
| 9 | + - '@c-r33d' |
| 10 | +--- |
| 11 | +# Allow Authz GetDecision/GetEntitlements requests to derive entity from request authorization token JWT |
| 12 | + |
| 13 | +## Context and Problem Statement |
| 14 | + |
| 15 | +Today, Authorization endpoints require entity specification on the request body, including one of a |
| 16 | +`Token` option, a `RegisteredResourceFQN` option, or an `EntityChain` option. |
| 17 | + |
| 18 | +In our SDKs, we prefer client-side interceptors to populate auth state within authenticated requests. |
| 19 | + |
| 20 | +When adding SDK support for a TDF `.Obligations()` method, it was realized we would need to add auth logic inside |
| 21 | +each SDK method itself (not their interceptors) to retrieve a valid access token and set it to a `GetDecision` request |
| 22 | +body as a `Token` entity. We had not exposed the ability serverside to check the request authorization token _as_ the entity |
| 23 | +in a decision/entitlements request, and would need to do more work clientside as a result. |
| 24 | + |
| 25 | +## Decision Drivers |
| 26 | + |
| 27 | +* Reduced SDK logic: |
| 28 | + - avoids roundtripping for an access token from the idP twice (once to auth the request, once to place in the body) |
| 29 | + - avoids complexity in the interceptors (check if we've already retrieved a token first, etc.) |
| 30 | +* Improved DX/UX: |
| 31 | + - effectively GetMyEntitlements, GetMyDecision |
| 32 | +* Security: |
| 33 | + - fewer access tokens retrieved by an SDK instance |
| 34 | + - no changes to casbin RBAC route authz policy |
| 35 | + - any users permitted to make GetDecision/GetEntitlement queries will only get to check their own tokens more easily (inherently more secure than ability to check someone else's) |
| 36 | + - tokens have already been available to in-process services, and this work builds upon that feature |
| 37 | + - no security footguns when decisioning/entitling as the request auth usage is _explicit_ not _implicit_ |
| 38 | + |
| 39 | +Note: platform security controls safeguarding request access tokens as platform-level resources (should an IPC PEP |
| 40 | +be allowed to touch an access token) is considered out of scope |
| 41 | + |
| 42 | +## Considered Options |
| 43 | + |
| 44 | +* **Option 1**: Get an Access Token outside the interceptor from the OAuth token source for request body entity _and_ another within the interceptor (two tokens retrieved) |
| 45 | +* **Option 2**: Get an Access Token outside the interceptor from the OAuth token source for request body entity _and_ reuse within interceptor (one token retrieved) |
| 46 | +* **Option 3**: Improve Authz endpoints to allow explicitly using the auth header token as the entity |
| 47 | + |
| 48 | +## Decision Outcome |
| 49 | + |
| 50 | +Chosen option: **Option 3**: Improve Authz endpoints to allow explicitly using the auth header token as the entity |
| 51 | + |
| 52 | +### Consequences |
| 53 | + |
| 54 | +* 🟩 **Good**, because better API UX/DX for use cases where a PEP auth == user auth |
| 55 | +* 🟩 **Good**, because keeps token handling logic in SDKs centralized |
| 56 | +* 🟩 **Good**, because simplified Obligations decision check flow |
| 57 | +* 🟩 **Good**, because explicit flag on request avoids footguns in super-privileged PEPs |
| 58 | +* 🟨 **Neutral**, because more complexity in a oneof proto, but there are 4 types of entities/entity sources |
0 commit comments