Skip to content

feat(fga): support ABAC context in check, whoCanAccess and whatCanTargetAccess - #348

Merged
yosiharan merged 5 commits into
mainfrom
feat/fga-abac
Aug 10, 2026
Merged

feat(fga): support ABAC context in check, whoCanAccess and whatCanTargetAccess#348
yosiharan merged 5 commits into
mainfrom
feat/fga-abac

Conversation

@yosiharan

Copy link
Copy Markdown
Contributor

Related Issues

Required for:
https://github.com/descope/etc/issues/17574

Related PRs

Upstream PRs

In a Nutshell

  • check, whoCanAccess, whatCanTargetAccess context overloads
  • check finally returns the relation and info
  • loadSchema finally returns version and conditions
  • New FGACondition / FGAConditionParam models
  • Docs + unit tests

Description

Adds ABAC support to the FGA and authz surfaces, mirroring CheckWithContext, WhoCanAccessWithContext and WhatCanTargetAccessWithContext in the Go SDK. Callers can pass a context map whose keys become variables for the CEL conditions defined in the schema; the map is only sent when non-empty, matching Go.

The response half is included because a context map is not usable without it. check previously built each result from allowed alone and dropped the relation echo and the whole info object, so there was no way to tell a conditional denial from a plain one; loadSchema dropped the schema version and its conditions. Both are now parsed into typed response models instead of hand-rolled Map casting.

These are overloads, not renames, and FGASchema keeps its single-argument constructor, so existing call sites are untouched.

Second of four stacked PRs — based on #347.

Must

  • Tests
  • Documentation (if applicable)

@yosiharan

Copy link
Copy Markdown
Contributor Author

@shuni review

@shuni-bot

shuni-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🐕 Review complete — View session on Shuni Portal 🐾

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐕 Shuni's Review

Adds ABAC context overloads to check, whoCanAccess and whatCanTargetAccess, and replaces the hand-rolled Map casting in check/loadSchema with typed response DTOs so relation, info, version and conditions finally survive.

Sniffed out 1 issue:

  • 1 🟢 LOW: loadSchema can hand back a null conditions list

Good bones — the overloads delegate cleanly, mapOf returns a mutable HashMap so the conditional put("context", …) is safe, the empty-context-not-sent behaviour is pinned by tests, and FGASchema keeps its 1-arg constructor so existing call sites still compile. Woof!

See inline comment for details.


Declared coverage: FULL — 13/13 changed files reviewed.

Comment thread src/main/java/com/descope/sdk/mgmt/impl/FGAServiceImpl.java
@yosiharan

Copy link
Copy Markdown
Contributor Author

@shuni review

@shuni-bot

shuni-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🐕 Review complete — View session on Shuni Portal 🐾

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐕 Shuni's Review

Adds ABAC context overloads to check, whoCanAccess and whatCanTargetAccess, and swaps the hand-rolled Map casting in check/loadSchema for typed DTOs so relation, info, version and conditions finally survive.

Sniffed out 1 issue:

  • 1 🟢 LOW: README example uses a namespace that doesn't match its own schema

Re-sniffed the previous finding: loadSchema now seeds conditions with an empty list before any early return, so the README's iterate-the-conditions example can't NPE — fixed, and pinned by testLoadSchema_ConditionsAreNeverNull. Delegation keeps validation intact, mapOf hands back a mutable HashMap so the conditional put("context", …) is safe, and FGASchema's 1-arg constructor keeps existing call sites compiling. Good bones! Woof!

See inline comment for details.


Declared coverage: FULL — 13/13 changed files reviewed.

Comment thread README.md Outdated
@yosiharan

Copy link
Copy Markdown
Contributor Author

@shuni review

@shuni-bot

shuni-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🐕 Review complete — View session on Shuni Portal 🐾

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐕 Shuni's Review

Adds ABAC context overloads to check, whoCanAccess and whatCanTargetAccess, and replaces the hand-rolled Map casting in check/loadSchema with typed DTOs so relation, info, version and conditions finally survive.

Sniffed out 1 issue:

  • 1 🟢 LOW: new missingContext list can come back null

Both earlier findings re-sniffed and confirmed fixed: the README snippet now queries document, and loadSchema seeds conditions before every return (pinned by testLoadSchema_ConditionsAreNeverNull). apiProxy.get/post route through the same exchange as the old getArray/postAndGetArray with FAIL_ON_UNKNOWN_PROPERTIES=false, mapOf hands back a mutable HashMap so the conditional put("context", …) is safe, and FGASchema's new 1-arg constructor keeps existing call sites compiling alongside @AllArgsConstructor. Good bones! Woof!

See inline comment for details.


Declared coverage: FULL — 13/13 changed files reviewed.

Comment thread src/main/java/com/descope/sdk/mgmt/impl/FGAServiceImpl.java
@yosiharan

Copy link
Copy Markdown
Contributor Author

@shuni review

@shuni-bot

shuni-bot Bot commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

🐕 Review complete — View session on Shuni Portal 🐾

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐕 Shuni's Review

Adds ABAC context overloads to check, whoCanAccess and whatCanTargetAccess, and swaps the hand-rolled Map casting in check/loadSchema for typed DTOs so relation, info, version and conditions finally survive.

No new issues — nothing survived verification this round.

All three earlier findings re-sniffed and confirmed fixed: check seeds missingContext with an empty list (FGAServiceImpl.java:137, pinned by testCheck_MissingInfoIsNotNull), loadSchema seeds conditions before every return, and the README snippet queries the document namespace its own schema declares. Also re-checked the rest: apiProxy.get/post route through the same exchange with FAIL_ON_UNKNOWN_PROPERTIES=false, mapOf returns a mutable HashMap so the conditional put("context", …) is safe, FGACheckResult(allowed, relation, info) matches the arg order used, and FGASchema's explicit 1-arg constructor keeps existing call sites compiling next to @AllArgsConstructor/@Builder. Good bones! Woof!


Declared coverage: FULL — 13/13 changed files reviewed.


Declared coverage: FULL — 13/13 changed files reviewed.

@yosiharan yosiharan left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self review done

@yosiharan
yosiharan marked this pull request as ready for review August 10, 2026 11:06
Base automatically changed from feat/fga-dry-run to main August 10, 2026 12:10
yosiharan and others added 5 commits August 10, 2026 15:10
…getAccess

Adds context overloads mirroring CheckWithContext, WhoCanAccessWithContext and
WhatCanTargetAccessWithContext in the Go SDK. The context map is sent only when
non-empty, and its keys become variables for the CEL conditions in the schema.

Also surfaces the response side, which was previously discarded: check now
returns the relation it was asked about and the info object (conditional,
missingContext, conditionalErr, factUsed), and loadSchema now returns the
schema version and its conditions.

Overloads rather than renames, and FGASchema keeps its single-argument
constructor, so existing callers are unaffected.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The README tells callers to iterate schema.getConditions(), so default it to an
empty list when the server omits the schema object or its conditions, matching
how check normalizes a missing info.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The surrounding example declares type document, so the query has to use it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Same reason as conditions: callers iterate it, and the server omits it when
nothing is missing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Only the conditions on the deciding path are evaluated, so "any schema
conditions" overstates it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@shuni-bot

shuni-bot Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

🐕 Review complete — View session on Shuni Portal 🐾

@shuni-bot shuni-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🐕 Shuni's Review

Re-sniffed after the rebase onto main (#347 is in, so the PR diff is now just the ABAC work). Adds context overloads to check, whoCanAccess and whatCanTargetAccess, and swaps the hand-rolled Map casting in check/loadSchema for typed DTOs so relation, info, version and conditions survive.

No new issues — nothing survived verification.

Delta since the last review is javadoc wording only ("evaluating any schema conditions" → "evaluating schema conditions") in AuthzService/FGAService; the code is byte-identical. All three earlier findings stay fixed: loadSchema seeds conditions before every return, check seeds info.missingContext, and the README snippet queries the document namespace its own schema declares. Re-confirmed on this checkout that mapOf returns a mutable HashMap (so the conditional put("context", …) is safe), apiProxy.get(URI, Class) routes through the same exchange as the getArray it replaces, and FGACheckResult(allowed, relation, info) matches the arg order used. Good bones! Woof!


Declared coverage: FULL — 13/13 changed files reviewed.


Declared coverage: FULL — 13/13 changed files reviewed.

@itaihanski itaihanski left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯

@yosiharan
yosiharan merged commit 045fc17 into main Aug 10, 2026
20 checks passed
@yosiharan
yosiharan deleted the feat/fga-abac branch August 10, 2026 12:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants