Skip to content

feat(fga): skip caching conditional check results + wire CheckWithContext#464

Open
yosiharan wants to merge 4 commits into
mainfrom
feat/abac-skip-conditional-cache
Open

feat(fga): skip caching conditional check results + wire CheckWithContext#464
yosiharan wants to merge 4 commits into
mainfrom
feat/abac-skip-conditional-cache

Conversation

@yosiharan

@yosiharan yosiharan commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

Related Issues

Resolves: https://github.com/descope/etc/issues/15115

Related PRs

Upstream PRs

In a Nutshell

  • Skip caching FGA check results with Conditional == true
  • Wire CheckWithContext through controller → service → SDK
  • Forward Conditional, MissingContext, ConditionalErr in gRPC response
  • Tests for context forwarding and conditional response fields

Description

Adds ABAC/CEL support to authzcache end-to-end:

  • UpdateCacheWithChecks now skips entries with Info.Conditional == true so context-dependent FGA decisions are always re-evaluated by authzservice rather than served from a stale cache.
  • CheckWithContext is threaded through the gRPC controller → service → SDK call chain, passing the caller-supplied CEL context map to authzservice.
  • The controller forwards Conditional, MissingContext, and ConditionalErr fields in the CheckResponseInfo proto.
  • Unit tests cover context forwarding and conditional response field mapping.

Depends on: #488 (backend monorepo migration)

Must

  • Tests

Copilot AI review requested due to automatic review settings April 19, 2026 13:48
@shuni-bot-dev

shuni-bot-dev Bot commented Apr 19, 2026

Copy link
Copy Markdown

🐕 Review complete — View session on Shuni Portal 🐾

@shuni-bot-dev shuni-bot-dev Bot left a comment

Copy link
Copy Markdown

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/CEL support: skips caching conditional check results, wires CheckWithContext through controller → service → SDK, and forwards new conditional info fields in the response proto.

Sniffed out 2 issues:

  • 1 🔴 CRITICAL: build is broken — authzservice proto dependency missing required fields
  • 1 🟡 MEDIUM: WhoCanAccess/WhatCanTargetAccess candidate filtering drops context silently

This one needs a bath before it can go out! 🐾

Comment thread internal/controllers/controller.go
}

func (a *authzCache) Check(ctx context.Context, relations []*descope.FGARelation) ([]*descope.FGACheck, error) {
return a.CheckWithContext(ctx, relations, nil)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 MEDIUM: filterWhoCanAccessCandidates and filterWhatCanTargetAccessCandidates (lines 181–202, 233–254) call a.Check() which delegates to CheckWithContext(ctx, relations, nil) — so candidate re-verification never passes the caller's extra context.

If a conditional relation was originally allowed because the caller supplied context, the nil-context re-check here could flip it to denied, silently filtering out valid candidates. This may be intentional (lookup cache doesn't carry context), but worth a comment or explicit design note since it's a subtle behavioral difference.

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.

[CLAUDE 🤖] Valid design concern — added a comment to filterWhoCanAccessCandidates explaining why nil context is safe here: UpdateCacheWithChecks never caches conditional results, so any candidate stored in the WhoCanAccess/WhatCanTargetAccess cache is guaranteed to be non-conditional and re-validates correctly with nil context.

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

  1. I don't see this comment nowhere
  2. comment doesn't compile into code :)

@yosiharan yosiharan May 12, 2026

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.

Ah sorry, I later removed this comment manually as it was redundant and confusing, should have updated the comment thread 🙏

Copilot AI 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.

Pull request overview

Adds end-to-end ABAC/CEL support by threading caller-provided context through the authzcache stack and preventing context-dependent (conditional) authorization decisions from being cached.

Changes:

  • Skip caching of conditional FGA check results to avoid serving stale, context-dependent decisions from cache.
  • Wire CheckWithContext through controller → service → SDK, forwarding the request’s CEL context map.
  • Expand Check API response info to include Conditional, MissingContext, and ConditionalErr.

Reviewed changes

Copilot reviewed 7 out of 8 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
internal/services/caches/projectauthzcache.go Skips caching FGACheckInfo.Conditional results in UpdateCacheWithChecks.
internal/services/caches/projectauthzcache_test.go Adds unit test asserting conditional results are not stored in cache.
internal/services/authz.go Introduces CheckWithContext and routes Check through it; calls SDK CheckWithContext.
internal/services/authz_mock.go Extends AuthzCacheMock with CheckWithContext support.
internal/services/authz_test.go Updates mocks/bench to use CheckWithContext* expectations/responses.
internal/controllers/controller.go Forwards request context map into CheckWithContext and returns additional check info fields.
go.mod Bumps github.com/descope/go-sdk dependency to v1.16.0.
go.sum Updates checksums for the go-sdk version bump.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/controllers/controller.go
Comment thread internal/controllers/controller.go
Comment thread internal/services/authz.go
@yosiharan yosiharan force-pushed the feat/abac-skip-conditional-cache branch 2 times, most recently from d54c59a to 3691015 Compare May 11, 2026 12:30
…text

- UpdateCacheWithChecks skips entries with Info.Conditional==true so
  context-dependent results are always re-evaluated by authzservice
- CheckWithContext threaded through controller, service, and SDK call
- Controller now forwards Conditional, MissingContext, ConditionalErr
  fields in the gRPC CheckResponse
- Unit tests updated to use CheckWithContextAssert/Response mocks;
  new test asserts conditional results are never served from cache

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@yosiharan yosiharan force-pushed the feat/abac-skip-conditional-cache branch from 2708e32 to 929b91e Compare May 11, 2026 12:43
@yosiharan yosiharan enabled auto-merge (squash) May 11, 2026 13:20
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.

3 participants