IamClient API
IamClient is the framework-agnostic transport core. It does HTTP + ES256 verification, fails closed, and touches no React. Construct one per app and hand it to IamProvider, or use it imperatively.
import { IamClient } from '@padosoft/laravel-iam-react-native';
Constructor
new IamClient(config: IamClientConfig)
Validates eagerly: throws if baseUrl is missing, not an absolute URL, or if no fetch is available. Trailing slashes on baseUrl are trimmed.
IamClientConfig
| Option | Type | Default | Description |
|---|---|---|---|
baseUrl |
string |
required | Full API base incl. route prefix, e.g. https://iam.example.com/api/iam/v1. Must be absolute. |
token |
string |
— | Service token (OAuth2 Client Credentials); sent as Authorization: Bearer. |
timeoutMs |
number |
2000 |
Per-request timeout (via AbortController). |
retries |
number |
0 |
Retries for idempotent network errors only (never on 4xx/5xx). Clamped to ≥ 0. |
cache |
CacheOptions |
off | { ttlMs, maxEntries? } in-memory decision cache. ttlMs > 0 enables it. |
verify |
VerifyOptions |
{} |
Defaults for verifyToken: { issuer?, audience?, jwksUri? }. |
fetch |
typeof fetch |
globalThis.fetch |
Inject a custom fetch (tests, proxies). |
checkPath |
string |
decisions/check |
Path appended to baseUrl for the PDP check. |
listResourcesPath |
string |
decisions/list-resources |
Path for ReBAC list-resources. |
A relative baseUrl is rejected at construction. Otherwise the issuer derivation for verifyToken would silently become undefined and JWKS resolution would throw outside the fail-closed path. Fail loud, once, at construction.
const iam = new IamClient({
baseUrl: 'https://iam.example.com/api/iam/v1',
token: process.env.IAM_SERVICE_TOKEN,
timeoutMs: 2000,
retries: 1,
cache: { ttlMs: 5000, maxEntries: 1000 },
verify: { audience: 'warehouse-app' },
});
check(query): Promise<Decision>
Asks the PDP POST {baseUrl}/decisions/check. Never throws — returns a normalised Decision. Fails closed to deny(...) on a missing subject, transport failure, non-2xx, or malformed body.
const decision = await iam.check({
subject: { type: 'user', id: 'usr_123' },
application: 'warehouse',
permission: 'stock.adjust',
resource: { type: 'warehouse', id: 'wh_milan' },
context: { amount: 300 },
// organization?, currentAal?, explain?
});
- Cache: used only when enabled and
explain !== true; a fresh hit short-circuits the network. explain: true: bypasses the cache entirely (read and write) for live reasoning.- See the DecisionQuery fields and the wire payload.
can(query): Promise<boolean>
check() reduced to the fail-safe boolean: isGranted(decision) = allowed && !requiresStepUp. Use this — not raw decision.allowed — when you only need yes/no imperatively.
if (await iam.can({ subject, permission: 'doc.publish', resource })) {
// permitted (and not pending step-up)
}
listResources(subject, relation): Promise<Resource[]>
ReBAC reverse lookup: POST {baseUrl}/decisions/list-resources. Returns the well-formed { type, id } entries the subject has the given relation to. Never throws; returns [] on a missing subject/relation, transport failure, or malformed body.
const warehouses = await iam.listResources({ type: 'user', id: 'usr_123' }, 'manager');
// → Resource[]
Treat an empty array as “show nothing”. See ReBAC list-resources.
verifyToken(jwt, options?): Promise<Claims>
Verifies an ES256 JWT against the server JWKS. Rejects with TokenVerificationError on any failure — this is the only method that throws, because a token has no safe fallback value.
const claims = await iam.verifyToken(jwt, {
// all optional; fall back to client `verify` defaults
audience: 'warehouse-app', // MANDATORY (here or in client `verify`)
issuer: 'https://iam.example.com',
jwksUri: 'https://iam.example.com/.well-known/jwks.json',
});
Behaviour:
- Audience is mandatory — rejects if neither
options.audiencenorverify.audienceis set (preventsaud-skip). - Algorithm pinned to
['ES256']. - Issuer defaults to the origin of
baseUrl; JWKS URI defaults to{origin}/.well-known/jwks.json. - JWKS cache: 10 minutes per URI, with one automatic refetch on a key-id miss (rotation).
- Empty/non-string
jwtrejects immediately.
VerifyOptions
| Field | Type | Description |
|---|---|---|
audience |
string | string[] |
Required (here or as a client default). Expected aud. |
issuer |
string |
Expected iss. Defaults to baseUrl origin. |
jwksUri |
string |
Override the JWKS URL. |
See Verifying tokens and the Hermes/Web Crypto runtime note.
Behaviour summary
| Method | Throws? | Fail-closed result |
|---|---|---|
check |
no | deny(reason) Decision |
can |
no | false |
listResources |
no | [] |
verifyToken |
yes | rejects TokenVerificationError |
Next steps
- Provider & Hooks API — the React surface over this client.
- Types —
DecisionQuery,Decision,Subject,Resource, … - Errors —
TokenVerificationError.