AXIAM PHP SDK

AuthzGrpcClient extends BaseStub
in package

FinalYes

gRPC authorization transport (CONTRACT.md §1/§6/§9, D-03/D-06/D-12).

PITFALL 4 / T-22-16 (extension_loaded('grpc') guard, high severity): this class extends \Grpc\BaseStub. PHP only resolves an extends clause's target when THIS FILE is actually included/executed (which PSR-4 autoloading defers until something references Axiam\Sdk\Grpc\AuthzGrpcClient by name) — so simply having this class exist in the SDK never fatals a REST-only runtime. The invariant this SDK MUST preserve is: nothing outside AuthzDispatcher's extension_loaded('grpc')-guarded branches may ever reference this class name (not a use import that gets executed, not a type-hint on a called method, not an instanceof check) — AuthzDispatcher is the ONLY call site in this SDK, and it references this class exclusively inside that guard.

No grpc_php_plugin was available in this development sandbox to generate a *ServiceClient stub (buf CLI unavailable — see 22-05-SUMMARY.md), so this class hand-implements CheckAccess/BatchCheckAccess directly against \Grpc\BaseStub::_simpleRequest() — the exact same primitive grpc_php_plugin's own generated service-client classes call internally, using the committed message stubs in Gen.

D-06: this class NEVER re-implements token refresh. $tokenAccessor is a non-blocking closure supplied by whatever assembles the client (AxiamClient, a later plan) that reads the CURRENT access token live — the exact same "read live, never cache a second copy" discipline Session::accessToken() already follows for REST. This class never triggers a refresh itself; on an UNAUTHENTICATED gRPC status it surfaces AuthError and lets the caller's own refresh-and-retry policy (mirroring RefreshMiddleware's REST behavior) decide whether to retry.

§6/D-12: the channel is ALWAYS constructed via \Grpc\ChannelCredentials::createSsl() (strict TLS, system trust roots) or, when $customCaPem is supplied, that same factory with the custom CA bytes — the ONLY escape hatch (§6). There is no insecure-channel construction path anywhere in this class.

§6.1 (mTLS): when a client identity ($clientCertPem + $clientKey) is configured it is passed to the SAME createSsl(rootCerts, privateKey, certChain) factory, so the channel presents a client certificate for mutual TLS. This is strictly additive — it changes only what the CLIENT presents, never how the server is verified (§6.1.2). The private key arrives wrapped in Sensitive and is revealed only at the createSsl() call site; it is never stored in plaintext, logged, or exposed.

§5: x-tenant-id metadata is injected on EVERY RPC; authorization metadata is injected whenever $tokenAccessor returns a non-empty token.

Table of Contents

Methods

__construct()  : mixed
batchCheckAccess()  : BatchCheckAccessResponse
`BatchCheckAccess` (CONTRACT.md §1) — results preserve input order.
checkAccess()  : CheckAccessResponse
`CheckAccess` (CONTRACT.md §1). `$tenantId`/`$subjectId` are cross-validated by the server against the verified JWT claims carried in the call's own auth metadata (SEC-003) — a mismatch is rejected server-side with `PERMISSION_DENIED`.

Methods

__construct()

public __construct(string $hostname, callable(): Array $tokenAccessor, string $tenantId[, string|null $customCaPem = null ][, string|null $clientCertPem = null ][, Sensitive|null $clientKey = null ][, array<string, mixed> $options = [] ]) : mixed
Parameters
$hostname : string

gRPC target, e.g. "api.axiam.example:9443".

$tokenAccessor : callable(): Array

Reads the CURRENT access token live (shares the Session single-flight refresh mechanism, D-06) — never caches a copy, never triggers a refresh itself.

$tenantId : string

Injected as the x-tenant-id metadata key on every RPC (§5).

$customCaPem : string|null = null

PEM-encoded custom CA bundle (§6's ONLY escape hatch); omit to use the system trust roots.

$clientCertPem : string|null = null

§6.1 (mTLS): PEM client-certificate chain this channel presents for mutual TLS; omit for bearer-token-only auth. Must be present together with $clientKey.

$clientKey : Sensitive|null = null

§6.1/§7 (mTLS): the matching private key, wrapped in Sensitive so it never leaks; revealed only to build the channel credentials, never retained in plaintext.

$options : array<string, mixed> = []

Additional \Grpc\BaseStub constructor options (e.g. a caller-supplied per-call deadline); credentials is always set by this constructor and cannot be overridden via $options.

batchCheckAccess()

`BatchCheckAccess` (CONTRACT.md §1) — results preserve input order.

public batchCheckAccess(BatchCheckAccessRequest $request) : BatchCheckAccessResponse
Parameters
$request : BatchCheckAccessRequest
Return values
BatchCheckAccessResponse

checkAccess()

`CheckAccess` (CONTRACT.md §1). `$tenantId`/`$subjectId` are cross-validated by the server against the verified JWT claims carried in the call's own auth metadata (SEC-003) — a mismatch is rejected server-side with `PERMISSION_DENIED`.

public checkAccess(string $tenantId, string $subjectId, string $action, string $resourceId[, string|null $scope = null ]) : CheckAccessResponse
Parameters
$tenantId : string
$subjectId : string
$action : string
$resourceId : string
$scope : string|null = null
Return values
CheckAccessResponse
On this page

Search results