Skip to content

feat(jans-cedarling): add batch authorize APIs for unsigned and multi-issuer flows#14615

Open
haileyesus2433 wants to merge 13 commits into
mainfrom
jans-cedarling-14434
Open

feat(jans-cedarling): add batch authorize APIs for unsigned and multi-issuer flows#14615
haileyesus2433 wants to merge 13 commits into
mainfrom
jans-cedarling-14434

Conversation

@haileyesus2433

@haileyesus2433 haileyesus2433 commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Prepare


Description

Target issue

closes #14434

Implementation Details


Test and Document the changes

  • Static code analysis has been run locally and issues have been fixed
  • Relevant unit and integration tests have been added/updated
  • Relevant documentation has been updated if any (i.e. user guides, installation and configuration guides, technical design docs etc)

Please check the below before submitting your PR. The PR will not be merged if there are no commits that start with docs: to indicate documentation changes or if the below checklist is not selected.

  • I confirm that there is no impact on the docs due to the code changes in this PR.

Summary by CodeRabbit

  • New Features

    • Added batch authorization APIs for unsigned and multi-issuer requests across core engine and bindings (C, Go, Java via UniFFI, JavaScript/WASM, Kotlin, Python, Rust), plus PostgreSQL SQL functions.
    • Batch responses include shared batch_id, preserve input order, and return per-item allow/deny decisions or per-item error details.
  • Documentation

    • Added “Batch Authorization” reference and tutorial guidance, including request/response formats and per-item failure categories.
  • Tests

    • Added validation, ordering/parity, and observability-focused coverage, including SQL integration tests and new batch benchmark scenarios.

haileyesus2433 and others added 6 commits July 7, 2026 02:08
…up helpers (#14502)

* feat(jans-cedarling): Add BatchValidationError to error and error
metrics

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): refactor entity building for batch processing
support

Introduce `unsigned_setup` and `multi_issuer_setup` to separate
resource-independent entity construction from per-item logic. This
enables sharing setup overhead across authorization requests in a batch.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization request and response
models

Implement `BatchAuthorizeUnsignedRequest`,
`BatchAuthorizeMultiIssuerRequest`,
and `BatchAuthorizeResponse` structs to support batch authorization
processing. Added validation logic to ensure correct request structure
and included unit tests for serialization and validation.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): refactor multi-issuer entity building for batch
support

Introduced `MultiIssuerSetupEntities` to separate resource-independent
entity construction. This allows batch authorization paths to compute
tokens and issuers once and reuse them across multiple resource checks.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): refactor unsigned principal construction for batch
support

Replace `build_entities_unsigned` with `build_unsigned_principal` to
decouple principal construction from resource construction. This allows
callers to amortize principal entity building across multiple
authorization requests.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

---------

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
…rization in core engine (#14511)

* feat(jans-cedarling): add batch authorization metrics

Track total batch calls and the cumulative number of items processed
within each interval to support analysis of batch authorization
performance.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): make BatchItem context optional and default to
empty object

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): refactor build_unsigned_principal to return a
struct

Introduce UnsignedPrincipalBuild to improve readability and
maintainability
of the return type instead of using a tuple.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support for unsigned
requests

Implement `authorize_unsigned_batch` to allow evaluating multiple
authorization items in a single call. Individual items are processed
using a shared principal and pushed-data snapshot, with per-item
audit correlation via a generated batch ID.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling):Expose `authorize_unsigned_batch` in both blocking
and async Cedarling

Added
`batch_id` to decision logs for audit correlation.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* tests(jans-cedarling): add tests for unsigned batch authorization

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support for multi-issuer
requests

Implemented `authorize_multi_issuer_batch` to evaluate multiple requests
sharing the same token validation setup, allowing for efficient batch
processing of multi-issuer authorization.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): expose `authorize_multi_issuer_batch` in both the
async and blocking

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): remove unused build_multi_issuer_entities helper

Clean up the multi-issuer entity construction flow by removing the
convenience wrapper and requiring callers to explicitly pair setup
entities with a resource entity. This promotes consistent usage across
both single-item and batch authorization paths.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add tests for authorize_multi_issuer_batch

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): index batch_id for log query by batch

batch_id now participates in get_additional_ids(), enabling
LogStorage::get_logs_by_request_id(batch_id) to retrieve all
decision entries for a batch call.

Also documents the indexability on DecisionLogEntry::batch_id,
DecisionLogMetadata::batch_id, and BatchAuthorizeResponse.

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>

* feat(jans-cedarling): index batch_id on LogEntry and attach to all batch logs

batch_id field + set_batch_id() on LogEntry, included in
get_additional_ids() for index lookup. Now applied to per-item
error logs and summary logs in both batch methods.

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>

* feat(jans-cedarling): Track total count and item volume for both
unsigned and multi-issuer.

authorization flows to provide more granular visibility into batch
processing performance.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

---------

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
Co-authored-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
#14519)

* feat(jans-cedarling): Add batch authorization methods to WASM bindings

Expose `authorizeUnsignedBatch` and `authorizeMultiIssuerBatch` to the
WASM interface, including the necessary response wrappers. Also derive
Clone for existing authorization result types to support batch response
creation.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): add tests for WASM batch authorization

Add unit tests for `authorize_unsigned_batch` and
`authorize_multi_issuer_batch` to verify correct handling of request
items and batch ID generation.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): Add batch authorization support to Python bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add BatchValidationError to Python bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add Python bindings for batch authorization

Implement `BatchItem`, `BatchAuthorizeUnsignedRequest`,
`BatchAuthorizeMultiIssuerRequest`, and their corresponding response
wrappers to support batch processing in the Python binding.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization tests for Python bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): regenerate PYTHON_TYPES.md

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization methods to UniFFI bindings

Expose `authorize_unsigned_batch` and `authorize_multi_issuer_batch`
methods in the `Cedarling` UniFFI interface to support processing
multiple
requests in a single call.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add unit tests for authorize_unsigned_batch

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support to
CedarlingAdapter

Added methods for unsigned and multi-issuer batch authorization, along
with a helper to construct batch items from JSON.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): Add unit tests for authorizeUnsignedBatch

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add UniFFI multi-issuer batch tests

Introduce integration tests for `authorize_multi_issuer_batch` to verify
UniFFI marshalling, batch ID generation, and result arity. Added
`test_utils` as a dev-dependency to support token claim generation.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add unit tests for authorizeMultiIssuerBatch

Add test coverage for multi-issuer batch authorization, verifying input
marshalling, result parity with single-item calls, and error handling
for empty inputs.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add structs for batch authorization requests and
responses

Implement custom JSON marshaling for BatchItem to ensure nil context
values
are serialized as empty objects for validation compatibility.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support to Go bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization methods to Go bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): regenerate gen.go

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization tests for Go bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add C API functions for batch authorization

Implement `authorize_unsigned_batch` and `authorize_multi_issuer_batch`
to support processing multiple authorization requests in a single call.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jasn-cedarling): add C FFI functions for batch authorization

Expose `cedarling_authorize_unsigned_batch` and
`cedarling_authorize_multi_issuer_batch` to allow processing multiple
authorization items in a single call.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add tests for batch authorization C bindings

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support to bridge module

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): handle batch validation errors in Cedarling
bridge

Include BatchValidation in error classification and add a diagnostic log
to ensure visibility of failures, as batch surface returns an empty
result set.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): implement batch authorization SQL functions

Adds `cedarling_authorize_unsigned_batch` and
`cedarling_authorize_multi_issuer_batch` set-returning functions. These
enable processing multiple authorization requests in a single call,
returning results with audit correlation IDs and supporting shadow mode
behavior.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add pg_test support for batch authorization
functions

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): regenerate schema file

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): refactor internal types and update documentation
for batch auth

- Change public struct definitions to `pub(crate)` to restrict
  visibility.
- Add `BatchValidationError` to handle context conversion errors.
- Document `batch_id` and `results` attributes in both types and
  documentation.
- Improve test assertions for batch authorization responses.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): update batch authorization documentation and test
cases

Clarify that batch result items correspond to input indices and add a
test verifying that mixed allow/deny results are correctly ordered.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jasn-cedarling): test mixed-decision ordering in batch
authorizations

Verify that batch authorization results maintain order and produce
distinguishable decisions when one item contains a malformed action UID
(resulting in a fail-closed Deny) among valid items. Added test cases
across Java, C, and WASM bindings.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add test for mixed-decision batch authorization

Ensures that batch results preserve input ordering and correctly
identify failed items when mixed with successful authorizations.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): regenerate schema file

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* refactor(jans-cedarling): C interface authorization logic

Introduce a shared `authorize_json` helper function to consolidate
repetitive boilerplate for instance resolution, request deserialization,
response serialization, and error handling across all authorization
entry
points.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): remove omitempty

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* fix(jans-cedarling): address coderabbit comments

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* fix(jans-cedarling): remaining coderabbit ai comments

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* fix(jans-cedarling): synthesize fail-closed rows for batch authorization
errors

Replace empty result sets on batch-level failures with fail-closed
rows to prevent accidental authorization bypasses. If the item count
is recoverable from the JSON request, emit one row per input item;
otherwise, emit a sentinel row at index -1.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jasn-cedarling): refactor batch authorization documentation

Condense internal documentation and comments for batch authorization
functions to improve clarity while preserving the technical details of
the
fail-closed contract.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* fix(jans-cedarling): batch authorization observability

- Add `batch_id` to `AuthorizationTrace` to correlate per-item traces.
- Record `total_requests` and individual item traces for batch calls,
  ensuring consistency with single-item observability.
- Ensure batch failures correctly increment the error counter.
- Add regression tests to verify status tracking and trace recording.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add tests for batch authorization modes and
cleanup

- Added tests for policy Deny, shadow mode, and fail-open behavior in
  unsigned batch authorization.
- Updated `BatchPgTestGuard` to reset `cedarling.mode` and
  `cedarling.fail_mode` after tests.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): assert individual authorization results in
test_authorize_multi_issuer_batch_ordered

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): add @Final decorator to batch request classes

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

---------

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
…sage (#14565)

* docs(jans-cedarling): Add batch authorization documentation for all
supported languages in tutorials

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* docs: Add documentation for batch authorization methods in reference's

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* docs: document batch authorization functions in Postgres docs

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

---------

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
…g contract coverage (#14564)

* chore(jans-cedarling): add batch benchmark scenarios to CONTRACT.md

Documented `unsigned_batch` and `multi_issuer_batch` scenarios,
including
the test harness methodology and updated schema definitions.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): add batch authorization benchmark scenarios

Added benchmark scenarios for unsigned and multi-issuer batch
authorization with 10 and 25 items to evaluate performance and setup
amortization.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): Add batch contract tests

Introduce cross-flow contract tests to ensure batch authorization
consistency, including result equivalence between single and batch
calls,
positional mapping stability, and batch_id log correlation.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add benchmark for batch authorization

Add `authz_authorize_batch_benchmark` to measure the performance of
batch versus sequential authorization requests for both unsigned and
multi-issuer flows.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add support for batch authorization benchmarks

- Register batch authorization functions in the C benchmark runner.
- Implement response validation for batch results, ensuring all
  decisions
  within a batch must be allowed.
- Update the generator script to support creating batch request
  payloads.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): Implement batch authorization benchmark support in
`cedarling_go`

- Consolidate and clarify documentation in `CONTRACT.md` and test
  modules.
- Simplify benchmark documentation strings in `scenarios.json`.
- Cleanup logic comments in C and Rust test suites.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support to Python
benchmarks

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add batch authorization support to Java benchmark

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add support for batch authorization scenarios to
benchmarks in wasm

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* fix(jans-cedarling): avoid int32 truncation in item_count

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>

* fix(jans-cedarling): clarify batch assertions

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>

* chore(jans-cedarling): add pre-benchmark validation for authorization
fixtures

Verify that all requests pass authorization before starting the
benchmark
timer to ensure fixture integrity and prevent measuring unexpected
denials.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): use iter_batched in authorization benchmarks

Refactor benchmark loops to use `iter_batched` to avoid cloning request
data within the timed block, improving measurement accuracy. Also update
the multi-issuer fixture to reuse the existing resource entity.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* fix(jans-cedarling): add integrity assertions to batch contract tests

Verify decision outcomes against expected patterns to detect fixture
drift
where tests might otherwise pass silently due to all-Deny results.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): Update comments in batch_contract test

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): clarify assert/expect messages in batch benchmarks

Messages now explain *why* an assertion exists (fixture validity,
batch-item-Allow invariant) instead of merely restating the operation.

Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>

---------

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
Signed-off-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
Co-authored-by: Oleh Bozhok <6554798+olehbozhok@users.noreply.github.com>
…thorizeResult, BatchItemError> (#14576)

* feat(jans-cedarling): add BatchItemError for granular batch
authorization failures

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): return BatchItemError for failed authorization
items

Update batch authorization methods to return `Result<T, BatchItemError>`
for individual items instead of synthesizing a `Deny` decision. Add a
classification helper to map internal authorization errors to the
serializable wire format.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* refactor(jans-cedarling): refine batch authorization tests to handle
`BatchItemError`

Update tests to explicitly check for `BatchItemError` rather than
expecting a `decision` field on error results. This ensures that
malformed requests (e.g., bad action UIDs) are correctly surfaced as
errors at the specific item index, preventing them from being
incorrectly treated as denials.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add per-item error handling to batch authorize
responses

Introduce `BatchItemUnsignedResult` and `BatchItemMultiIssuerResult` to
wrap individual batch results. Each result can now explicitly represent
either a successful `AuthorizeResult` or a `BatchItemError` describing
why the item failed to reach the Cedar engine.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): update Python batch authorization tests to handle
Result types

Refactor tests to explicitly verify Result status before unwrapping, and
add assertions to validate error surfaces in batch processing for
malformed actions.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): update Go bindings to handle per-item batch
results

Implement discriminated union types for batch authorization results to
properly distinguish between successful decisions and per-item build
errors. Added `IsOk()` helpers and updated tests to reflect this change
in error surfacing.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling):Support per-item error reporting in batch
authorization in uniffi bindings

Introduce `BatchItemUnsignedOutcome` and `BatchItemMultiIssuerOutcome`
enums to allow batch response results to represent either a successful
authorization or a specific item failure. Update UniFFI bindings to
propagate these errors, enabling callers to identify which specific
items
in a batch failed and why.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add per-item error handling to batch authorization
WASM bindings

Updates the batch authorization response structures to include
`BatchItemError` information. This allows callers to distinguish between
authorized decisions and per-item build failures, providing better
diagnostic visibility into failed batch operations.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add error_category column to batch authorization
results

Expose item-level build errors in batch authorization results by adding
an `error_category` column to the SQL response. This distinguishes cases
where Cedar failed to evaluate a request from valid authorization
denials.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): add helper methods to CedarlingAdapter for batch
outcomes

Introduce `isOk`, `unwrap`, and `getError` helpers for both unsigned and
multi-issuer batch outcomes to simplify processing and validation in the
Java bindings. Updated existing tests to utilize these new methods.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): update batch authorization tests to match new
wire format

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): update benchmark authorization logic for outcome
types

Update C, Go, Java, and WASM benchmarks to correctly handle the Result
type patterns used in batch authorization responses. This ensures
that errors are explicitly checked before accessing decision values.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): regenerate the cedarling_pg schema

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): update documentation for batch authorization
response

Refine the batch response schema description, detail `BatchItemError`
variants, and update the JavaScript usage example to reflect the
current result handling pattern.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): update Postgres batch functions to include
error_category

Add an `error_category` column to the return table for batch
authorization functions to provide granular insight into per-item
build failures and batch-level errors.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): update batch authorization documentation

Clarify batch response structures and error handling patterns across all
supported language tutorials to reflect the `Ok`/`Err` result model.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): regenerate PYTHON_TYPES.md

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): apply coderabbit comments

Clarify in documentation and code comments that per-item batch failures
are returned as `BatchItemError` rather than synthesized as
"fail-closed"
denies. Added `__repr__` for Python bindings and included verification
tests to ensure consistency between error categories and serialized wire
formats.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* feat(jans-cedarling): improve batch item error handling and reporting

Replace incorrect PyRuntimeError usage with PyValueError and add an
unreachable check for batch-level errors in per-item classification.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): derive Debug for authz bridge structs and improve
batch error tracing

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

* chore(jans-cedarling): address coderabbit comments

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

---------

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
@haileyesus2433 haileyesus2433 added this to the 2.3.0 milestone Jul 23, 2026
@haileyesus2433 haileyesus2433 self-assigned this Jul 23, 2026
@mo-auto

mo-auto commented Jul 23, 2026

Copy link
Copy Markdown
Member

Snyk checks have passed. No issues have been found so far.

Status Scan Engine Critical High Medium Low Total (0)
Open Source Security 0 0 0 0 0 issues

💻 Catch issues earlier using the plugins for VS Code, JetBrains IDEs, Visual Studio, and Eclipse.

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Batch authorization is added to Cedarling for unsigned and multi-issuer flows, with shared setup, ordered per-item outcomes, validation and error contracts, batch correlation, PostgreSQL functions, language bindings, tests, benchmarks, and documentation.

Changes

Batch authorization

Layer / File(s) Summary
Core contracts and orchestration
jans-cedarling/cedarling/src/authz/*, .../entity_builder/*, .../log/*
Adds batch request/response types, validation errors, per-item failures, shared authorization setup, metrics, and batch_id log correlation.
Binding APIs and adapters
jans-cedarling/bindings/cedarling_{c,go,java,python,uniffi,wasm}/*
Exposes unsigned and multi-issuer batch authorization with request conversion, result wrappers, error handling, and boundary coverage.
PostgreSQL integration
jans-cedarling/cedarling_pg/*
Adds SQL batch functions returning per-item rows, sentinel failure handling, mode semantics, traces, metrics, and integration tests.
Benchmarks and fixtures
jans-cedarling/cedarling/benches/*, jans-cedarling/bindings/benchmarks/*
Adds batch-versus-sequential benchmarks, scenario generation, fixture definitions, and validation helpers.
Documentation and tutorials
docs/cedarling/*, jans-cedarling/bindings/cedarling_python/PYTHON_TYPES.md
Documents batch request shapes, outcomes, errors, SQL rows, correlation, and usage across supported integrations.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: kind-feature, area-documentation, comp-docs, comp-jans-cedarling

Suggested reviewers: olehbozhok, dagregi, 0xtinkle, tareknaser

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the PR’s main change: adding batch authorize APIs for unsigned and multi-issuer flows.
Description check ✅ Passed The description matches the required template and includes the target issue and checklist, but the implementation details section is sparse.
Linked Issues check ✅ Passed The code adds both batch APIs and shared batch setup paths for unsigned and multi-issuer authorization, matching issue #14434.
Out of Scope Changes check ✅ Passed The extra docs, tests, and benchmark updates support the batch API work and do not appear unrelated to the issue.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch jans-cedarling-14434

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot added area-documentation Documentation needs to change as part of issue or PR comp-docs Touching folder /docs comp-jans-cedarling Touching folder /jans-cedarling kind-feature Issue or PR is a new feature request labels Jul 23, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 19

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/cedarling/integrations/postgres.md`:
- Around line 293-295: Update the failure-row contract table to document a
boolean value for decision that matches the declared decision bool column, while
retaining finalize_error as the error/failure semantics through the appropriate
error field.

In `@docs/cedarling/reference/cedarling-authz.md`:
- Line 563: Update the variant documentation around item_index to remove the
claim that it remains stable under reordering, and state instead that result
slots preserve positional correspondence with the items collection. Keep the
existing descriptions of message and item_index otherwise unchanged.

In `@docs/cedarling/tutorials/java.md`:
- Around line 285-297: Update the Java batch example to remove the undefined
principalJson reference: in the authorizeUnsignedBatchEntity call, reuse the
previously defined principal EntityData value, or declare principalJson before
use if the JSON overload is intended. Keep the example consistent with the
preceding principal definition.

In `@jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c`:
- Around line 719-730: Extract the repeated strstr-based counting loops from
test_authorize_unsigned_batch and test_authorize_unsigned_batch_mixed_ordering
into a shared static count_occurrences helper that advances by the needle
length, then replace the inline ok_count, err_count, allow_count, and
request_ids loops with calls to it while preserving their existing assertions.

In
`@jans-cedarling/bindings/cedarling_python/src/authorize/batch_authorize_response.rs`:
- Around line 8-9: Restore import ordering in batch_authorize_response.rs (lines
8-9), batch_item.rs (lines 8-12), request_batch_multi_issuer.rs (lines 8-10),
and request_batch_unsigned.rs (lines 8-10) by placing all external crate
imports, including pyo3, before the corresponding super/internal imports.

In `@jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_error.rs`:
- Around line 13-14: Correct the BatchItemError PyO3 docstring in
jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_error.rs:13-14
to describe results[i].error as a property and identify these as per-item
preparation/validation failures, not Cedar reachability failures. Regenerate the
derived documentation in
jans-cedarling/bindings/cedarling_python/PYTHON_TYPES.md:152-153 so it reflects
the corrected source text.

In `@jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_result.rs`:
- Around line 68-71: Update the BatchItemMultiIssuerResult documentation to
directly describe its is_ok(), unwrap(), and error APIs, including their
expected behavior, rather than referring users to BatchItemUnsignedResult. Keep
the documentation suitable for copying into PYTHON_TYPES.md.

In `@jans-cedarling/bindings/cedarling_python/src/cedarling.rs`:
- Around line 214-215: The documentation for the unsigned batch API incorrectly
describes per-item failures as synthesized Deny results; update the comment near
the unsigned batch method to describe them as error outcomes represented by
BatchItemError entries that callers must inspect. Apply the equivalent wording
correction to the multi-issuer batch documentation near the corresponding
method.

In `@jans-cedarling/bindings/cedarling_uniffi/src/tests.rs`:
- Around line 485-486: Add descriptive assertion messages for both category and
item-index checks at
jans-cedarling/bindings/cedarling_uniffi/src/tests.rs:485-486,
jans-cedarling/bindings/cedarling_wasm/src/tests.rs:1260-1261, and
jans-cedarling/bindings/cedarling_wasm/src/tests.rs:1396-1397. Use messages that
explain the expected error category and that the item index matches the
malformed batch item's position.

In `@jans-cedarling/bindings/cedarling_wasm/src/lib.rs`:
- Around line 218-261: Add # Arguments and # Example documentation sections to
the exported authorize_unsigned_batch and authorize_multi_issuer_batch methods,
describing the request parameter and showing representative JavaScript usage
consistent with the documentation style of other exported methods in the file.
- Around line 210-260: Extract the repeated Map-to-Object normalization into a
private helper on the surrounding binding type, preserving the existing behavior
and error propagation. Update authorize_unsigned_batch and
authorize_multi_issuer_batch to call the helper, and apply the same helper to
the existing authorize_unsigned and authorize_multi_issuer methods so all four
entry points use one implementation.

In
`@jans-cedarling/bindings/cedarling-java/src/main/java/io/jans/cedarling/binding/wrapper/CedarlingAdapter.java`:
- Around line 230-256: Extract the duplicated Map<String, String> to
List<TokenInput> conversion and null key/value validation into a shared private
helper, such as toTokenInputs(Map<String, String>), covering both
authorizeMultiIssuer(Map, ...) and authorizeMultiIssuerBatch(Map, ...). Replace
each inline loop with this helper while preserving the existing validation
messages and TokenInput ordering.

In `@jans-cedarling/cedarling_pg/src/functions/authorized.rs`:
- Around line 355-362: Remove the duplicate finalize_batch_decision logic and
reuse finalize_decision for batch results. Update success_rows to call
finalize_decision with raw_decision, preserving the existing Shadow-mode true
result and raw decision behavior for other modes.
- Around line 384-405: Update the failure-row construction in the batch error
match to return an empty string for the tuple’s SQL batch_id column in both the
N-row and sentinel branches. Preserve batch_id_val exclusively for
batch_id_trace correlation and keep the existing trace behavior unchanged.

In `@jans-cedarling/cedarling/src/authz/mod.rs`:
- Around line 858-866: The resource construction in the unsigned batch path
should propagate the `BuildEntityError` from `build_resource_entity` directly as
`AuthorizeError::BuildEntity`, rather than converting it through
`BuildUnsignedEntityError`. Update the error mapping around
`try_batch_item_unsigned` so `classify_batch_item_error` produces
`ResourceBuild`, while retaining `BuildUnsignedEntityError` handling for
unsigned principal or role setup failures.

In `@jans-cedarling/cedarling/src/authz/request.rs`:
- Around line 520-638: Update the batch request tests around
batch_unsigned_validates_valid_request and
batch_multi_issuer_validates_valid_request to use validate().expect(...) for
successful validation checks instead of assert!(...). Add descriptive messages
to every assertion in these tests, including assert_eq!, assert!, and round-trip
checks, while preserving the existing expected values and test behavior.

In `@jans-cedarling/cedarling/src/entity_builder/build_multi_issuer_entity.rs`:
- Around line 650-651: Update the setup-builder tests around
build_multi_issuer_setup_entities in
jans-cedarling/cedarling/src/entity_builder/build_multi_issuer_entity.rs at
lines 650-651, 695-696, and 889-890 to replace each is_ok assertion and
subsequent unwrap with result.expect("descriptive message"). At lines 923-927,
bind result.expect_err("all invalid tokens must fail setup") before matching the
expected error.

In `@jans-cedarling/cedarling/src/tests/authorize_unsigned_batch.rs`:
- Around line 67-73: The batch tests contain assertions without descriptive
failure messages. In authorize_unsigned_batch.rs, update the results.len() and
batch_id assertions at lines 67-73, 107, 147, and 184; in
authorize_multi_issuer_batch.rs, update the corresponding assertions at lines
97-102, 126, and 151. Add clear messages explaining the expected result count
and non-nil batch ID for each assertion.

In `@jans-cedarling/cedarling/src/tests/batch_contract.rs`:
- Around line 411-424: Update the batch log assertions in the batch contract
test to require exactly three entries with logs.len() == 3, confirming every
valid item emitted a correlated log. Add a descriptive failure message to the
final assert_eq! comparing each entry’s batch_id with batch_id_str.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: df77326c-2ada-4354-b216-6198eb775891

📥 Commits

Reviewing files that changed from the base of the PR and between f39894d and f8afcf5.

⛔ Files ignored due to path filters (1)
  • jans-cedarling/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (81)
  • docs/cedarling/integrations/postgres.md
  • docs/cedarling/reference/cedarling-authz.md
  • docs/cedarling/reference/cedarling-multi-issuer.md
  • docs/cedarling/tutorials/c.md
  • docs/cedarling/tutorials/go.md
  • docs/cedarling/tutorials/java.md
  • docs/cedarling/tutorials/javascript.md
  • docs/cedarling/tutorials/kotlin.md
  • docs/cedarling/tutorials/python.md
  • docs/cedarling/tutorials/rust.md
  • jans-cedarling/bindings/benchmarks/CONTRACT.md
  • jans-cedarling/bindings/benchmarks/fixtures/scenarios.json
  • jans-cedarling/bindings/cedarling-java/src/main/java/io/jans/cedarling/binding/wrapper/CedarlingAdapter.java
  • jans-cedarling/bindings/cedarling-java/src/test/java/io/jans/cedarling/binding/wrapper/MultiIssuerBatchAuthzTest.java
  • jans-cedarling/bindings/cedarling-java/src/test/java/io/jans/cedarling/binding/wrapper/UnsignedBatchAuthzTest.java
  • jans-cedarling/bindings/cedarling_c/benchmarks/benchmark_cedarling.c
  • jans-cedarling/bindings/cedarling_c/benchmarks/gen_scenarios.py
  • jans-cedarling/bindings/cedarling_c/src/c_interface.rs
  • jans-cedarling/bindings/cedarling_c/src/lib.rs
  • jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c
  • jans-cedarling/bindings/cedarling_go/benchmarks/main.go
  • jans-cedarling/bindings/cedarling_go/cedarling.go
  • jans-cedarling/bindings/cedarling_go/cedarling_batch_test.go
  • jans-cedarling/bindings/cedarling_go/internal/gen.go
  • jans-cedarling/bindings/cedarling_go/internal/methods.go
  • jans-cedarling/bindings/cedarling_go/src/cedarling_interface.rs
  • jans-cedarling/bindings/cedarling_go/src/lib.rs
  • jans-cedarling/bindings/cedarling_go/structs.go
  • jans-cedarling/bindings/cedarling_python/PYTHON_TYPES.md
  • jans-cedarling/bindings/cedarling_python/benchmarks/benchmark_cedarling.py
  • jans-cedarling/bindings/cedarling_python/cedarling_python/authorize_errors.pyi
  • jans-cedarling/bindings/cedarling_python/cedarling_python/cedarling_python.pyi
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_authorize_response.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_item.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_error.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_result.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/errors.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/mod.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/request_batch_multi_issuer.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/request_batch_unsigned.rs
  • jans-cedarling/bindings/cedarling_python/src/cedarling.rs
  • jans-cedarling/bindings/cedarling_python/tests/test_authorize_multi_issuer_batch.py
  • jans-cedarling/bindings/cedarling_python/tests/test_authorize_unsigned_batch.py
  • jans-cedarling/bindings/cedarling_uniffi/Cargo.toml
  • jans-cedarling/bindings/cedarling_uniffi/javaApp/src/main/java/org/example/Benchmark.java
  • jans-cedarling/bindings/cedarling_uniffi/src/lib.rs
  • jans-cedarling/bindings/cedarling_uniffi/src/result.rs
  • jans-cedarling/bindings/cedarling_uniffi/src/tests.rs
  • jans-cedarling/bindings/cedarling_wasm/benchmarks/benchmark.mjs
  • jans-cedarling/bindings/cedarling_wasm/src/lib.rs
  • jans-cedarling/bindings/cedarling_wasm/src/tests.rs
  • jans-cedarling/cedarling/Cargo.toml
  • jans-cedarling/cedarling/benches/authz_authorize_batch_benchmark.rs
  • jans-cedarling/cedarling/src/authz/error_metrics.rs
  • jans-cedarling/cedarling/src/authz/errors.rs
  • jans-cedarling/cedarling/src/authz/metrics.rs
  • jans-cedarling/cedarling/src/authz/mod.rs
  • jans-cedarling/cedarling/src/authz/request.rs
  • jans-cedarling/cedarling/src/blocking.rs
  • jans-cedarling/cedarling/src/entity_builder/build_multi_issuer_entity.rs
  • jans-cedarling/cedarling/src/entity_builder/build_resource_entity.rs
  • jans-cedarling/cedarling/src/entity_builder/mod.rs
  • jans-cedarling/cedarling/src/lib.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling/src/log/log_entry.rs
  • jans-cedarling/cedarling/src/log/stdout_logger/native_logger.rs
  • jans-cedarling/cedarling/src/log/test.rs
  • jans-cedarling/cedarling/src/tests/authorize_multi_issuer_batch.rs
  • jans-cedarling/cedarling/src/tests/authorize_unsigned_batch.rs
  • jans-cedarling/cedarling/src/tests/batch_contract.rs
  • jans-cedarling/cedarling/src/tests/mod.rs
  • jans-cedarling/cedarling_pg/sql/cedarling_pg--0.1.0.sql
  • jans-cedarling/cedarling_pg/src/authz/bridge.rs
  • jans-cedarling/cedarling_pg/src/functions/authorized.rs
  • jans-cedarling/cedarling_pg/src/functions/authorized_row.rs
  • jans-cedarling/cedarling_pg/src/functions/error.rs
  • jans-cedarling/cedarling_pg/src/functions/mod.rs
  • jans-cedarling/cedarling_pg/src/functions/pg_test_authorize_batch.rs
  • jans-cedarling/cedarling_pg/src/lib.rs
  • jans-cedarling/cedarling_pg/src/observability/log.rs
  • jans-cedarling/cedarling_pg/src/observability/trace.rs

Comment thread docs/cedarling/integrations/postgres.md Outdated
Comment thread docs/cedarling/reference/cedarling-authz.md Outdated
Comment thread docs/cedarling/tutorials/java.md
Comment thread jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c Outdated
Comment thread jans-cedarling/cedarling/src/authz/mod.rs Outdated
Comment thread jans-cedarling/cedarling/src/authz/request.rs
Comment thread jans-cedarling/cedarling/src/tests/authorize_unsigned_batch.rs
Comment thread jans-cedarling/cedarling/src/tests/batch_contract.rs

@coderabbitai coderabbitai 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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
docs/cedarling/reference/cedarling-authz.md (1)

574-586: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Define request in the batch example.

The example calls authorize_unsigned_batch(request) without declaring request; copied as-is, it raises a ReferenceError. Add a minimal request or state that it was defined earlier.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cedarling/reference/cedarling-authz.md` around lines 574 - 586, Update
the batch authorization example around authorize_unsigned_batch to define a
minimal request before it is passed to the method, or explicitly state that
request is defined earlier, so the copied example does not reference an
undeclared variable.
jans-cedarling/cedarling/src/lib.rs (1)

285-290: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Document the new public batch methods.

Add Rust docstrings describing the request, ordered per-item results, shared batch_id, and batch-level versus per-item errors.

As per coding guidelines, public API items must have docstrings.

Also applies to: 312-319

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lib.rs` around lines 285 - 290, Document the
public methods authorize_unsigned_batch and the additional batch method near it
with Rust doc comments. Describe the request, ordered per-item results, shared
batch_id, and the distinction between batch-level errors and per-item
BatchItemError results, without changing their behavior.

Source: Coding guidelines

docs/cedarling/tutorials/javascript.md (1)

297-324: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add the batch methods and result types to the TypeScript API declaration.

The Cedarling declaration later in this file exposes authorize_unsigned and authorize_multi_issuer, but not either batch method or its result/error wrappers. TypeScript consumers therefore cannot compile the documented batch calls.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cedarling/tutorials/javascript.md` around lines 297 - 324, Update the
TypeScript API declarations for the Cedarling class to expose
authorize_unsigned_batch and authorize_multi_issuer_batch, including their
request, response, result-wrapper, and BatchItemError types. Match the
documented is_ok, unwrap(), error, batch_id, and positional item-result behavior
so TypeScript consumers can compile the batch examples.
jans-cedarling/bindings/cedarling_wasm/src/lib.rs (1)

219-226: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Document per-item failures as errors, not synthesized Deny decisions.

The batch APIs return BatchAuthorizeResponse<Result<..., BatchItemError>>, and the WASM wrappers expose failed items via is_ok=false and error. A real Cedar denial is an AuthorizeResult with decision=false; the current wording describes different behavior and may cause callers to discard item errors.

Also applies to: 246-251

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/bindings/cedarling_wasm/src/lib.rs` around lines 219 - 226,
Update the batch authorization documentation near BatchAuthorizeUnsignedResponse
and the corresponding section around BatchAuthorizeResponse to state that
per-item failures are returned as BatchItemError results and exposed by WASM
with is_ok=false and error, while genuine Cedar denials remain AuthorizeResult
values with decision=false. Remove the claim that failures synthesize
fail-closed Deny decisions or do not affect other items.
jans-cedarling/cedarling/src/lock/transport/mapping.rs (1)

285-307: 📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win

Add descriptive messages to the modified assertions.

The assertions in these changed test ranges omit the required explanation of what failed. Add a message argument to each assert_eq!, assert!, and matches! assertion.

Also applies to: 320-325, 349-349, 366-366, 400-402, 431-436, 460-460, 487-487

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs` around lines 285 -
307, Add descriptive failure messages to every modified assert_eq!, assert!, and
matches! assertion in the relevant lock mapping tests, including the assertions
around lock_entry fields and context_information and the additional referenced
ranges. Make each message identify the specific field or condition being
validated, without changing the assertion logic.

Source: Coding guidelines

jans-cedarling/bindings/benchmarks/fixtures/scenarios.json (1)

263-267: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use non-expired tokens in the batch benchmark fixtures.

The exp claims 1724945978 and 1724835859 are already expired as of July 23, 2026. Cedarling’s shared multi-issuer setup still validates expiration, so these scenarios will fail before measuring batch authorization. Refresh the tokens or generate them at runtime.

Also applies to: 299-303

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/bindings/benchmarks/fixtures/scenarios.json` around lines 263
- 267, Update the batch benchmark fixture payloads associated with the affected
token scenarios so their exp claims are valid at execution time. Refresh both
expired tokens, or generate them dynamically if the fixture supports it, while
preserving the existing multi-issuer and authorization claims.
jans-cedarling/bindings/cedarling_wasm/benchmarks/benchmark.mjs (1)

138-146: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Pass an object to the batch WASM APIs.

runScenario stringifies the request, but authorize_unsigned_batch and authorize_multi_issuer_batch deserialize the received JsValue as an object; they do not parse JSON strings. Consequently, every batch benchmark scenario will fail during request decoding and be skipped.

Keep both representations and use the JSON string only for the single-request APIs.

Proposed fix
-function pickInvoker(cedarling, scenario, request) {
+function pickInvoker(cedarling, scenario, request, request_json) {
...
-        (await cedarling.authorize_unsigned(request)).decision;
+        (await cedarling.authorize_unsigned(request_json)).decision;
...
-        (await cedarling.authorize_multi_issuer(request)).decision;
+        (await cedarling.authorize_multi_issuer(request_json)).decision;
...
-    const request = JSON.stringify(buildRequest(scenario));
-    const invoke = pickInvoker(cedarling, scenario, request);
+    const request = buildRequest(scenario);
+    const request_json = JSON.stringify(request);
+    const invoke = pickInvoker(cedarling, scenario, request, request_json);

Also applies to: 169-170

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/bindings/cedarling_wasm/benchmarks/benchmark.mjs` around lines
138 - 146, Update runScenario so it preserves the original request object for
authorize_unsigned_batch and authorize_multi_issuer_batch, passing that object
directly to both batch WASM APIs. Restrict JSON.stringify(request) to the
single-request API paths, while keeping the existing batch result handling
unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@docs/cedarling/reference/cedarling-authz.md`:
- Around line 574-586: Update the batch authorization example around
authorize_unsigned_batch to define a minimal request before it is passed to the
method, or explicitly state that request is defined earlier, so the copied
example does not reference an undeclared variable.

In `@docs/cedarling/tutorials/javascript.md`:
- Around line 297-324: Update the TypeScript API declarations for the Cedarling
class to expose authorize_unsigned_batch and authorize_multi_issuer_batch,
including their request, response, result-wrapper, and BatchItemError types.
Match the documented is_ok, unwrap(), error, batch_id, and positional
item-result behavior so TypeScript consumers can compile the batch examples.

In `@jans-cedarling/bindings/benchmarks/fixtures/scenarios.json`:
- Around line 263-267: Update the batch benchmark fixture payloads associated
with the affected token scenarios so their exp claims are valid at execution
time. Refresh both expired tokens, or generate them dynamically if the fixture
supports it, while preserving the existing multi-issuer and authorization
claims.

In `@jans-cedarling/bindings/cedarling_wasm/benchmarks/benchmark.mjs`:
- Around line 138-146: Update runScenario so it preserves the original request
object for authorize_unsigned_batch and authorize_multi_issuer_batch, passing
that object directly to both batch WASM APIs. Restrict JSON.stringify(request)
to the single-request API paths, while keeping the existing batch result
handling unchanged.

In `@jans-cedarling/bindings/cedarling_wasm/src/lib.rs`:
- Around line 219-226: Update the batch authorization documentation near
BatchAuthorizeUnsignedResponse and the corresponding section around
BatchAuthorizeResponse to state that per-item failures are returned as
BatchItemError results and exposed by WASM with is_ok=false and error, while
genuine Cedar denials remain AuthorizeResult values with decision=false. Remove
the claim that failures synthesize fail-closed Deny decisions or do not affect
other items.

In `@jans-cedarling/cedarling/src/lib.rs`:
- Around line 285-290: Document the public methods authorize_unsigned_batch and
the additional batch method near it with Rust doc comments. Describe the
request, ordered per-item results, shared batch_id, and the distinction between
batch-level errors and per-item BatchItemError results, without changing their
behavior.

In `@jans-cedarling/cedarling/src/lock/transport/mapping.rs`:
- Around line 285-307: Add descriptive failure messages to every modified
assert_eq!, assert!, and matches! assertion in the relevant lock mapping tests,
including the assertions around lock_entry fields and context_information and
the additional referenced ranges. Make each message identify the specific field
or condition being validated, without changing the assertion logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 09864412-c102-425e-87f4-222fea9377ad

📥 Commits

Reviewing files that changed from the base of the PR and between f8afcf5 and de1d480.

⛔ Files ignored due to path filters (1)
  • jans-cedarling/Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (15)
  • docs/cedarling/reference/cedarling-authz.md
  • docs/cedarling/reference/cedarling-multi-issuer.md
  • docs/cedarling/tutorials/java.md
  • docs/cedarling/tutorials/javascript.md
  • docs/cedarling/tutorials/kotlin.md
  • jans-cedarling/bindings/benchmarks/fixtures/scenarios.json
  • jans-cedarling/bindings/cedarling_uniffi/Cargo.toml
  • jans-cedarling/bindings/cedarling_uniffi/src/lib.rs
  • jans-cedarling/bindings/cedarling_wasm/benchmarks/benchmark.mjs
  • jans-cedarling/bindings/cedarling_wasm/src/lib.rs
  • jans-cedarling/bindings/cedarling_wasm/src/tests.rs
  • jans-cedarling/cedarling/Cargo.toml
  • jans-cedarling/cedarling/src/lib.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling/src/log/log_entry.rs

JSON strings

Replaces `JsValue` with `&str` for `authorize_unsigned_batch` and
`authorize_multi_issuer_batch` to simplify the binding interface and
improve serialization performance.

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
- Clean up WASM error handling and string formatting
- Fix test utilities and documentation comments
- Improve safety and type handling in Postgres bindings
- Optimize hex string formatting in masking logic

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jans-cedarling/cedarling_pg/src/functions/authorized.rs`:
- Line 392: Reformat the push_batch_error_trace call in the surrounding batch
error-handling function to comply with the project’s 100-character rustfmt
limit, wrapping its arguments across lines without changing behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 10b5c462-78c4-4651-8a05-47c2c2cb7715

📥 Commits

Reviewing files that changed from the base of the PR and between de1d480 and e0cead4.

📒 Files selected for processing (10)
  • jans-cedarling/bindings/cedarling_wasm/src/lib.rs
  • jans-cedarling/bindings/cedarling_wasm/src/tests.rs
  • jans-cedarling/cedarling/src/authz/errors.rs
  • jans-cedarling/cedarling/src/lock/transport/test_utils.rs
  • jans-cedarling/cedarling/src/tests/batch_contract.rs
  • jans-cedarling/cedarling_pg/src/authz/where_clause.rs
  • jans-cedarling/cedarling_pg/src/functions/authorized.rs
  • jans-cedarling/cedarling_pg/src/functions/error.rs
  • jans-cedarling/cedarling_pg/src/mask/config.rs
  • jans-cedarling/cedarling_pg/src/mask/types.rs

Comment thread jans-cedarling/cedarling_pg/src/functions/authorized.rs Outdated
Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (7)
docs/cedarling/tutorials/javascript.md (1)

302-310: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Serialize the batch request before calling the API.

authorize_unsigned_batch is documented as accepting a JSON string, but this example passes the object directly. Use JSON.stringify(request) to match the API declaration and reference documentation.

Proposed fix
-const response = await cedarling.authorize_unsigned_batch(request);
+const response = await cedarling.authorize_unsigned_batch(JSON.stringify(request));
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cedarling/tutorials/javascript.md` around lines 302 - 310, Update the
authorize_unsigned_batch call in the JavaScript tutorial to pass
JSON.stringify(request) rather than the request object directly, matching the
API’s documented JSON-string input while leaving the request construction
unchanged.
jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c (1)

783-785: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align the test comment with the asserted error contract.

These lines say the malformed action “synthesizes fail-closed Deny,” but the test expects a per-item Err with action_parse and no decision:false. Update the comment to describe the actual Err behavior.

Proposed comment fix
-    // N=3 items: [ok, bad-action-Deny, ok]. Item[1] carries a malformed action
-    // UID → synthesizes fail-closed Deny. Verifies results[i] carries the
+    // N=3 items: [ok, bad-action-error, ok]. Item[1] carries a malformed action
+    // and surfaces a per-item Err. Verifies results[i] preserves input ordering
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c` around lines 783
- 785, Update the test comment near the batch-item setup to state that the
malformed action produces a per-item Err with the action_parse error and no
decision:false value, rather than synthesizing a fail-closed Deny. Keep the
comment’s description of per-item result alignment unchanged.
jans-cedarling/cedarling/src/authz/request.rs (1)

528-565: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Run rustfmt on the changed assertions. These lines exceed the repository’s 100-column Rust limit.

  • jans-cedarling/cedarling/src/authz/request.rs#L528-L565: wrap the three single-line assert_eq! calls.
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs#L285-L308: wrap the long mapping assertions.
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs#L350-L350: wrap the timestamp-error assertion.
  • jans-cedarling/bindings/cedarling_uniffi/src/tests.rs#L485-L486: wrap both error-property assertions.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/authz/request.rs` around lines 528 - 565, Run
rustfmt and wrap assertions exceeding the 100-column limit: update the three
assertions in jans-cedarling/cedarling/src/authz/request.rs:528-565, the long
mapping assertions in
jans-cedarling/cedarling/src/lock/transport/mapping.rs:285-308, the
timestamp-error assertion at
jans-cedarling/cedarling/src/lock/transport/mapping.rs:350, and both
error-property assertions in
jans-cedarling/bindings/cedarling_uniffi/src/tests.rs:485-486, preserving their
existing assertions and behavior.

Source: Coding guidelines

jans-cedarling/bindings/benchmarks/fixtures/scenarios.json (1)

268-278: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Replace the expired multi-issuer batch JWT fixtures.

Both new batch scenarios embed tokens that expired in August 2024, so token validation can fail before benchmarking authorization.

  • jans-cedarling/bindings/benchmarks/fixtures/scenarios.json#L268-L278: regenerate the multi_issuer_batch_10 token.
  • jans-cedarling/bindings/benchmarks/fixtures/scenarios.json#L306-L316: regenerate the multi_issuer_batch_25 token.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/bindings/benchmarks/fixtures/scenarios.json` around lines 268
- 278, Replace the expired JWT payloads in
jans-cedarling/bindings/benchmarks/fixtures/scenarios.json at lines 268-278 for
multi_issuer_batch_10 and lines 306-316 for multi_issuer_batch_25. Regenerate
both multi-issuer batch token fixtures with valid, non-expired tokens while
preserving their existing mappings and scenario structure.
jans-cedarling/cedarling/src/authz/mod.rs (2)

347-352: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Align helper documentation with actual pushed-data ownership.

Both helper descriptions claim that setup snapshots pushed data, but snapshotting occurs in the surrounding batch methods via get_pushed_data().

  • jans-cedarling/cedarling/src/authz/mod.rs#L347-L352: describe multi_issuer_setup as token/issuer setup only.
  • jans-cedarling/cedarling/src/authz/mod.rs#L706-L711: describe unsigned_setup as principal/entity setup only.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/authz/mod.rs` around lines 347 - 352, Update the
documentation for multi_issuer_setup at
jans-cedarling/cedarling/src/authz/mod.rs:347-352 to describe token/issuer setup
only and remove the claim that it snapshots pushed data. Update unsigned_setup
at jans-cedarling/cedarling/src/authz/mod.rs:706-711 similarly to describe
principal/entity setup only; leave pushed-data snapshot ownership documented in
the surrounding batch methods that call get_pushed_data().

399-403: 🚀 Performance & Scalability | 🔵 Trivial | 🏗️ Heavy lift

Share the immutable pushed-data snapshot across batch items.

Both loops deep-clone the full pushed-data map before building each item’s context, which can dominate batch cost for large snapshots.

  • jans-cedarling/cedarling/src/authz/mod.rs#L399-L403: pass shared/borrowed pushed data to multi-issuer context construction.
  • jans-cedarling/cedarling/src/authz/mod.rs#L752-L758: apply the same shared-snapshot approach to unsigned context construction.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@jans-cedarling/cedarling/src/authz/mod.rs` around lines 399 - 403, Update
both batch-item context construction sites in
jans-cedarling/cedarling/src/authz/mod.rs:399-403 and 752-758 to pass the
immutable pushed-data snapshot by shared reference or another non-cloning
mechanism instead of calling clone per item. Adjust the relevant
try_batch_item_multi_issuer and unsigned-context construction APIs as needed
while preserving each item’s existing context behavior.
jans-cedarling/bindings/cedarling-java/src/main/java/io/jans/cedarling/binding/wrapper/CedarlingAdapter.java (1)

167-174: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Document per-item failures as errors, not Deny outcomes.

These Javadocs say batch item failures synthesize fail-closed Deny results, but the returned BatchItem...Outcome exposes a failed outcome containing BatchItemError; only a successful outcome with decision=false is a genuine Cedar denial. This mismatch can cause Java callers to discard error categories and item indexes.

Also applies to: 211-217

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@jans-cedarling/bindings/cedarling-java/src/main/java/io/jans/cedarling/binding/wrapper/CedarlingAdapter.java`
around lines 167 - 174, Update the Javadocs for the batch authorization methods
around the shown documentation and the corresponding section near lines 211–217
to state that per-item failures return failed outcomes containing
BatchItemError, while only successful outcomes with decision=false represent
Cedar Deny decisions. Preserve the distinction between batch-level exceptions
and per-item error results, including item indexes and error categories.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jans-cedarling/bindings/cedarling_python/PYTHON_TYPES.md`:
- Around line 164-165: Update the BatchItemMultiIssuerResult heading in
PYTHON_TYPES.md from setext syntax to an ATX heading using a single leading #,
and remove the underline.

In `@jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_error.rs`:
- Around line 13-14: Add a Python-style Attributes section to the PyO3-exposed
type docstring near the batch item error documentation, documenting category:
str, item_index: int, and message: str. Preserve the existing description while
ensuring the generated Python documentation exposes these field type hints.

In `@jans-cedarling/bindings/cedarling_wasm/src/tests.rs`:
- Line 1331: The assertions at
jans-cedarling/bindings/cedarling_wasm/src/tests.rs lines 1331-1331 and
1469-1469 exceed the configured width; run rustfmt or manually apply its
standard multiline formatting to wrap both the unsigned batch and multi-issuer
batch assertions without changing their assertions or messages.

---

Outside diff comments:
In `@docs/cedarling/tutorials/javascript.md`:
- Around line 302-310: Update the authorize_unsigned_batch call in the
JavaScript tutorial to pass JSON.stringify(request) rather than the request
object directly, matching the API’s documented JSON-string input while leaving
the request construction unchanged.

In `@jans-cedarling/bindings/benchmarks/fixtures/scenarios.json`:
- Around line 268-278: Replace the expired JWT payloads in
jans-cedarling/bindings/benchmarks/fixtures/scenarios.json at lines 268-278 for
multi_issuer_batch_10 and lines 306-316 for multi_issuer_batch_25. Regenerate
both multi-issuer batch token fixtures with valid, non-expired tokens while
preserving their existing mappings and scenario structure.

In `@jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c`:
- Around line 783-785: Update the test comment near the batch-item setup to
state that the malformed action produces a per-item Err with the action_parse
error and no decision:false value, rather than synthesizing a fail-closed Deny.
Keep the comment’s description of per-item result alignment unchanged.

In
`@jans-cedarling/bindings/cedarling-java/src/main/java/io/jans/cedarling/binding/wrapper/CedarlingAdapter.java`:
- Around line 167-174: Update the Javadocs for the batch authorization methods
around the shown documentation and the corresponding section near lines 211–217
to state that per-item failures return failed outcomes containing
BatchItemError, while only successful outcomes with decision=false represent
Cedar Deny decisions. Preserve the distinction between batch-level exceptions
and per-item error results, including item indexes and error categories.

In `@jans-cedarling/cedarling/src/authz/mod.rs`:
- Around line 347-352: Update the documentation for multi_issuer_setup at
jans-cedarling/cedarling/src/authz/mod.rs:347-352 to describe token/issuer setup
only and remove the claim that it snapshots pushed data. Update unsigned_setup
at jans-cedarling/cedarling/src/authz/mod.rs:706-711 similarly to describe
principal/entity setup only; leave pushed-data snapshot ownership documented in
the surrounding batch methods that call get_pushed_data().
- Around line 399-403: Update both batch-item context construction sites in
jans-cedarling/cedarling/src/authz/mod.rs:399-403 and 752-758 to pass the
immutable pushed-data snapshot by shared reference or another non-cloning
mechanism instead of calling clone per item. Adjust the relevant
try_batch_item_multi_issuer and unsigned-context construction APIs as needed
while preserving each item’s existing context behavior.

In `@jans-cedarling/cedarling/src/authz/request.rs`:
- Around line 528-565: Run rustfmt and wrap assertions exceeding the 100-column
limit: update the three assertions in
jans-cedarling/cedarling/src/authz/request.rs:528-565, the long mapping
assertions in jans-cedarling/cedarling/src/lock/transport/mapping.rs:285-308,
the timestamp-error assertion at
jans-cedarling/cedarling/src/lock/transport/mapping.rs:350, and both
error-property assertions in
jans-cedarling/bindings/cedarling_uniffi/src/tests.rs:485-486, preserving their
existing assertions and behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f2630a0d-758a-4ac4-98a1-66e9da8cf4be

📥 Commits

Reviewing files that changed from the base of the PR and between e0cead4 and d2d1767.

📒 Files selected for processing (23)
  • docs/cedarling/integrations/postgres.md
  • docs/cedarling/reference/cedarling-authz.md
  • docs/cedarling/tutorials/java.md
  • docs/cedarling/tutorials/javascript.md
  • jans-cedarling/bindings/benchmarks/fixtures/scenarios.json
  • jans-cedarling/bindings/cedarling-java/src/main/java/io/jans/cedarling/binding/wrapper/CedarlingAdapter.java
  • jans-cedarling/bindings/cedarling_c/tests/test_cedarling.c
  • jans-cedarling/bindings/cedarling_python/PYTHON_TYPES.md
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_authorize_response.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_item.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_error.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/batch_item_result.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/request_batch_multi_issuer.rs
  • jans-cedarling/bindings/cedarling_python/src/authorize/request_batch_unsigned.rs
  • jans-cedarling/bindings/cedarling_python/src/cedarling.rs
  • jans-cedarling/bindings/cedarling_uniffi/src/tests.rs
  • jans-cedarling/bindings/cedarling_wasm/src/lib.rs
  • jans-cedarling/bindings/cedarling_wasm/src/tests.rs
  • jans-cedarling/cedarling/src/authz/mod.rs
  • jans-cedarling/cedarling/src/authz/request.rs
  • jans-cedarling/cedarling/src/lib.rs
  • jans-cedarling/cedarling/src/lock/transport/mapping.rs
  • jans-cedarling/cedarling_pg/src/functions/authorized.rs

Comment thread jans-cedarling/bindings/cedarling_python/PYTHON_TYPES.md
Comment thread jans-cedarling/bindings/cedarling_wasm/src/tests.rs
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 24, 2026
checks

Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>
Signed-off-by: haileyesus2433 <haileyesusbe@gmail.com>

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@jans-cedarling/scripts/check_benchmarks.py`:
- Around line 8-12: Update EXCLUDE_BENCHMARKS so it does not exclude the entire
multi-issuer benchmark groups for n10 and n25; retain coverage for their batch
measurements. Exclude only the sequential leaf benchmark names, or apply a
separate threshold to the sequential baseline if that is the intended handling.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: b827cef6-0d4c-4f53-b37e-6614cb57498a

📥 Commits

Reviewing files that changed from the base of the PR and between d2d1767 and c633018.

📒 Files selected for processing (2)
  • jans-cedarling/cedarling_pg/sql/cedarling_pg--0.1.0.sql
  • jans-cedarling/scripts/check_benchmarks.py

Comment thread jans-cedarling/scripts/check_benchmarks.py
@olehbozhok

Copy link
Copy Markdown
Contributor

@haileyesus2433 pls check #14615 (review) maybe some of the comments worth fixing in the current PR

@olehbozhok

olehbozhok commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

Batch Authorization — Code Review

Summary

Overall the code is production-ready. Found 3 bugs (2 in batch code, 1 pre-existing exposed by the diff). No blockers.


Issues

1. WASM unwrap() throws wrong error

File: bindings/cedarling_wasm/src/lib.rs:740 and :778

// BatchItemUnsignedResult::unwrap
.map_err(|e| Error::new(e.message()))  // ← raw BatchItemError message

// BatchItemMultiIssuerResult::unwrap — same pattern
.map_err(|e| Error::new(e.message()))

Throws raw BatchItemError.message (e.g., "item 1: action parse failed: ...") instead of a descriptive error like "BatchItemUnsignedResult is Err". Python/Java correctly throw a struct-label message (PyValueError("BatchItemUnsignedResult is Err") / IllegalStateException("BatchItemUnsignedOutcome is Failed")).

The unwrap() error should tell the caller they misused the API (tried to unwrap a failed result), not the underlying reason the item failed. The raw failure reason is already available via the .error property.

Fix:

.map_err(|_| Error::new("BatchItemUnsignedResult is Err"))
// and
.map_err(|_| Error::new("BatchItemMultiIssuerResult is Err"))

at lib.rs:740 and lib.rs:778.


2. log_failed_diagnostics missing batch_id

File: cedarling/src/authz/mod.rs:1056

log_failed_diagnostics has no batch_id parameter and never calls .set_batch_id(). Batch path callers at mod.rs:452 and mod.rs:810 call it without batch_id, even though the decision logs at the same call sites DO set batch_id: Some(batch_id) at mod.rs:447 and mod.rs:805.

Denied-diagnostics log entries are not retrievable via get_logs_by_request_id(batch_id).

Fix: add batch_id: Option<Uuid> parameter to log_failed_diagnostics and call .set_batch_id(batch_id).


3. Divergent error wrapping for build_resource_entity (pre-existing bug)

File: cedarling/src/authz/mod.rs:574-579 vs mod.rs:860-862

The single-item authorize_unsigned wraps build_resource_entity failures in BuildUnsignedEntityError → maps to AuthorizeError::BuildUnsignedRoleEntity — which displays "failed to build role entities for unsigned request" and would classify as BatchItemError::PrincipalBuild. But it's a resource entity build failure, not a role/principal error.

The batch path try_batch_item_unsigned does it correctly: wraps as AuthorizeError::BuildEntity → maps to BatchItemError::ResourceBuild.

This is a pre-existing bug in the single-item path. The batch code chose the correct variant. Both paths should use the same wrapping.

Fix at mod.rs:574-579:

.map_err(|e| {
    self.config.metrics.record_error(&e);
    self.config.metrics.record_authz_error();
    AuthorizeError::BuildEntity(e)
})?;

Low Priority

  • C binding has no dedicated batch unit tests — only benchmark integration (bindings/cedarling_c/tests/)
  • WASM missing multi-issuer empty-tokens/empty-items rejection tests (bindings/cedarling_wasm/src/tests.rs)
  • check_benchmarks.py:8 — no comment explaining why multi_issuer_batch_vs_sequence_n10/n25 are excluded (likely because they require gen_mock_server HTTP servers that aren't available in CI)
  • pushed_data.clone() per-item — O(items × data), could be Arc-shared (mod.rs:402, mod.rs:757)
  • setup_entities.tokens.clone() per item — full HashMap clone, could be Arc-wrapped (mod.rs:517)
  • Go benchmark clonePayload — shallow map copy, safe for current fixtures but fragile (bindings/cedarling_go/benchmarks/main.go:313)
  • Lock transport — no test coverage for DecisionLogEntry with non-None batch_id (cedarling_pg/src/lock/transport/test_utils.rs:68)

Verified Correct

  • Core logic: error partitioning (batch-level vs per-item) is sound; unreachable!() arms are genuinely unreachable
  • Row contract: bool_and(decision) never collapses to NULL; sentinel rows at item_index = -1 work correctly
  • Mode handling: shadow/enforcement + fail_mode open/closed correct on all paths (success, per-item error, batch failure)
  • Observability: record_decision only for Ok items, record_error_msg for Err + batch-level, matches documented contract
  • batch_id indexing: properly included in get_additional_ids()get_logs_by_request_id(batch_id) works
  • All 7 bindings (C, Go, Java, Python, WASM, UniFFI/Kotlin) consistent in API surface
  • Test coverage: core has cross-flow equivalence tests (batch_contract.rs), PG has 9 pg_test functions
  • Go BatchItemError.Variantjson:"variant" correctly matches core serde #[serde(tag = "variant")]

.build_resource_entity(&request.resource)
.map_err(|e| {
self.config.metrics.record_error(&e);
let wrapped = crate::entity_builder::MultiIssuerEntityError::EntityCreationFailed(

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.

I think one thing got lost on the way when we split build_multi_issuer_entities into build_multi_issuer_setup_entities + a per-item build_resource_entity. The old function logged an ERROR entry when the resource entity failed to build:

.inspect_err(|e| {
    log_service.log_any(
        LogEntry::new(BaseLogEntry::new_system_opt_request_id(LogLevel::ERROR, None))
            .set_message("Failed to build resource entity for multi-issuer authorization".to_string())
            .set_error(e.to_string()),
    );
})

That log entry is gone now so a resource-build failure on authorize_multi_issuer still bumps the metrics but no longer writes anything to the log store.

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.

The batch path does log per-item failures (log_any with set_error) so single-item and batch behave differently here now.

/// Validate the batch request structure. See [`BatchValidationError`] for
/// the possible failure modes.
pub fn validate(&self) -> Result<(), BatchValidationError> {
if self.items.is_empty() {

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.

validate() checks for an empty items and a non-object context but nothing caps the length. Then Vec::with_capacity(request.items.len()) allocates on a caller-controlled number and the loop runs to completion with no early exit.

I am thinking about the Postgres surface: cedarling_authorize_unsigned_batch(request_json text) is callable by any role with EXECUTE and it's VOLATILE PARALLEL RESTRICTED so one SELECT with a big items array pins a backend for as long as it takes to evaluate every item.

The docs even suggest "deciding which N rows in a query result the current principal may see" where N is whatever the query returned.

Is there a max batch size somewhere I've missed?

/// "context": {...} }, ... ] }`. The response body carries `batch_id` (UUIDv7
/// string) alongside `results` — one `AuthorizeResult` per input item, in
/// input order. Batch-level failures (validation, principal parse) return an
/// error; per-item failures synthesize a fail-closed `Deny` for that item

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.

afaik since #14576 a per-item failure comes back as {"Err": {...}} rather than a synthesized Deny so this doc comment describes the old contract. A C caller reading it would look for results[i].decision and instead find an Err envelope.

The same wording is still in cedarling_authorize_multi_issuer_batch here in authorize_unsigned_batch / authorize_multi_issuer_batch in cedarling_uniffi/src/lib.rs, and in AuthorizeUnsignedBatch / AuthorizeMultiIssuerBatch in cedarling_go/cedarling.go.

I see that the Python docstrings were updated to "returned as BatchItemError entries that callers must inspect"

push_trace(AuthorizationTrace {
timestamp: timestamp.clone(),
action: item.action,
duration_ms: total_ms,

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.

Each item's trace gets the whole batch's elapsed time so a 25-item batch that took 50ms writes 25 traces each claiming 50ms. Anything that sums or averages duration_ms across traces then overcounts by roughly N which is the opposite of the story a batch is supposed to tell

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.

I don't think the core gives you a per-item duration in the response today (the per-item decision time is only in the decision log) so I'm not sure what the right fix is

BatchItemError::ContextBuild { message, item_index }
},
AuthorizeError::BuildEntity(_) => BatchItemError::ResourceBuild { message, item_index },
AuthorizeError::BuildUnsignedRoleEntity(_) => {

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.

Tracing the per-item path, I don't think this arm can fire. BuildUnsignedRoleEntity only comes out of build_unsigned_principal which only runs in unsigned_setup and a failure there returns Err(AuthorizeError) for the whole batch before any item gets classified. So principal_build looks like a category that can never appear in results[i] even though the BatchItemError variants table in cedarling-authz.md documents it as a per-item failure.

also i noticed the unreachable!() at the bottom panics inside a library. C is safe (ffi_guard_int! wraps everything in catch_unwind) and uniffi/PyO3 turn panics into exceptions but on wasm32-unknown-unknown there's no unwinding

we can add a catch-all arm (falling back to something like SchemaValidation, or a new Internal variant) plus a debug_assert! be safer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-documentation Documentation needs to change as part of issue or PR comp-docs Touching folder /docs comp-jans-cedarling Touching folder /jans-cedarling kind-feature Issue or PR is a new feature request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(jans-cedarling): add batch authorize APIs for unsigned and multi-issuer flows

4 participants