AuthzRestClient
in package
REST authorization transport (FND-04, CONTRACT.md §1): `checkAccess()`/`can()`/ `batchCheck()` over `POST /api/v1/authz/check[/batch]` — the ALWAYS-available authz path (D-03). Reuses the caller-supplied Guzzle client (the same instance {@see \Axiam\Sdk\Session} wires with {@see AuthMiddleware}/{@see RefreshMiddleware} on its `HandlerStack`), so `Authorization`/`X-Tenant-ID`/`X-CSRF-Token` header injection and the single-flight refresh-on-401 behavior (D-06) apply to authz calls exactly as they do to every other REST call — this class never re-implements any of that.
Wire field names match crates/axiam-api-rest/src/handlers/authz_check.rs exactly:
action, resource_id (camelCase resourceId on the PHP call surface, snake_case on
the wire), optional scope. tenant_id is never sent in the body — the server
derives it from the verified JWT (SEC-003). subject_id is likewise omitted by
default (the server falls back to deriving the subject from the same verified JWT,
i.e. whichever session's Bearer token is attached to the request) — but CONTRACT.md
§11.2.2 (declarative authorization helpers) requires an explicit, additive
subject_id override: AccessEnforcer calls a shared AXIAM client
on behalf of the REQUEST's authenticated end user, which is a different identity
than whatever session the shared client itself is authenticated as (typically a
service account) — omitting subject_id in that scenario would silently check the
service account's permissions instead of the end user's. See
self::checkAccess()'s $subjectId parameter.
Table of Contents
Methods
- __construct() : mixed
- batchCheck() : array<int, bool>
- `batchCheck` (CONTRACT.md §1): `POST /api/v1/authz/check/batch`. `$checks` is a list of `[action, resourceId, scope?]` tuples; the returned list of `allowed` booleans preserves input order exactly, matching `BatchCheckAccessResponse::results` on the server (same order/length guarantee).
- batchCheckDecisions() : array<int, AccessDecision>
- `POST /api/v1/authz/check/batch` returning the **full** decisions, including each `reason_code` (§11 rule 9). Results preserve input order.
- can() : bool
- `can` (CONTRACT.md §1): the ergonomic browser/UI-scenario alias for {@see self::checkAccess()} — same endpoint, same semantics (§1 note: "`can` is an alias for `check_access`").
- checkAccess() : bool
- `checkAccess` (CONTRACT.md §1). `POST /api/v1/authz/check`. Returns the decoded `allowed` boolean; non-2xx responses are translated via {@see ErrorMapper} (403 -> `AuthzError`, 401 -> `AuthError`, everything else -> `NetworkError`).
- checkAccessDecision() : AccessDecision
- `POST /api/v1/authz/check` returning the **full** decision, including the CONTRACT.md §11 rule 9 `reason_code`.
Methods
__construct()
public
__construct(Client $http[, DecisionMemo|null $memo = null ][, TelemetryDispatcher|null $telemetry = null ][, bool $retry = true ][, callable(): float|null $jitter = null ][, callable(float): void|null $sleep = null ]) : mixed
Parameters
- $http : Client
-
The Guzzle client.
- $memo : DecisionMemo|null = null
-
§17 memo; disabled when omitted.
- $telemetry : TelemetryDispatcher|null = null
-
§19 dispatcher; inert when omitted.
- $retry : bool = true
-
§16.1 disable switch.
- $jitter : callable(): float|null = null
-
Injected jitter draw, for tests.
- $sleep : callable(float): void|null = null
-
Injected sleep, for tests.
batchCheck()
`batchCheck` (CONTRACT.md §1): `POST /api/v1/authz/check/batch`. `$checks` is a list of `[action, resourceId, scope?]` tuples; the returned list of `allowed` booleans preserves input order exactly, matching `BatchCheckAccessResponse::results` on the server (same order/length guarantee).
public
batchCheck(array<int, array{action: string, resourceId: string, scope?: string|null}> $checks) : array<int, bool>
Parameters
- $checks : array<int, array{action: string, resourceId: string, scope?: string|null}>
Return values
array<int, bool>batchCheckDecisions()
`POST /api/v1/authz/check/batch` returning the **full** decisions, including each `reason_code` (§11 rule 9). Results preserve input order.
public
batchCheckDecisions(array<int, array{action: string, resource_id: string, scope?: string|null, subject_id?: string|null}> $checks) : array<int, AccessDecision>
Parameters
- $checks : array<int, array{action: string, resource_id: string, scope?: string|null, subject_id?: string|null}>
Return values
array<int, AccessDecision>can()
`can` (CONTRACT.md §1): the ergonomic browser/UI-scenario alias for {@see self::checkAccess()} — same endpoint, same semantics (§1 note: "`can` is an alias for `check_access`").
public
can(string $resource, string $action) : bool
Parameters
- $resource : string
- $action : string
Return values
boolcheckAccess()
`checkAccess` (CONTRACT.md §1). `POST /api/v1/authz/check`. Returns the decoded `allowed` boolean; non-2xx responses are translated via {@see ErrorMapper} (403 -> `AuthzError`, 401 -> `AuthError`, everything else -> `NetworkError`).
public
checkAccess(string $action, string $resourceId[, string|null $scope = null ][, string|null $subjectId = null ]) : bool
Parameters
- $action : string
- $resourceId : string
- $scope : string|null = null
- $subjectId : string|null = null
-
Additive, optional (CONTRACT.md §11.2.2): when given, sent on the wire as
subject_idso the server evaluates the check for THIS subject rather than whichever identity the calling client's own Bearer token represents.null(the default) preserves the pre-§11 behavior exactly — nosubject_idfield is sent, and the server derives the subject from the verified JWT as before.
Return values
boolcheckAccessDecision()
`POST /api/v1/authz/check` returning the **full** decision, including the CONTRACT.md §11 rule 9 `reason_code`.
public
checkAccessDecision(string $action, string $resourceId[, string|null $scope = null ][, string|null $subjectId = null ]) : AccessDecision
Exists because self::checkAccess() returns a bare bool that predates that
field and cannot carry it without a breaking signature change. The distinction it
surfaces is not cosmetic: no_grant means "ask an admin for access",
denied_by_rule means "an admin has already decided", and an application that
cannot tell them apart sends users to raise tickets that will be refused.
Parameters
- $action : string
- $resourceId : string
- $scope : string|null = null
- $subjectId : string|null = null