Policy simulator

Ask the policy simulator whether a principal in your account would be allowed to perform an action on a resource — the same 10-step evaluation the platform runs, so the answer you get is the answer the platform enforces.

It is a simulator, in the shape of AWS IAM’s SimulatePrincipalPolicy: you may ask only about your own account, it requires a dedicated permission on top of your access key, it is rate-limited, and every call is audited.

Endpoint

Method

Path

Purpose

POST

/identity/v1/authorize

Simulate one request → ALLOW / DENY

POST

/identity/v1/authorize/batch

Simulate many requests in one call

Base URL: https://api.flexgalaxy.ai.

Before you can simulate

The simulator requires the managed permission IamPolicySimulateAccess to be attached to the service user whose access key you sign with. A valid access key alone is not sufficient: without the permission the request is refused with 403 (policy-simulate-required). Attach the policy the same way you attach any managed policy to a service user; account root users pass without it.

Authentication

This endpoint is authenticated with FGAI-HMAC-SHA256 request signing using an account service-user access key — not a bearer token. Issue a key for your service as described in [CLI & service authentication](https://docs.flexgalaxy.ai/dev/dotid/cli-authentication/), then sign each request with these headers:

Header

Value

Authorization

FGAI-HMAC-SHA256 Credential=<access-key-id>/<date>/<region>/<service>/fgai4_request, SignedHeaders=..., Signature=...

X-FGAI-Date

Request timestamp, yyyyMMddTHHmmssZ (UTC)

X-FGAI-Content-SHA256

Hex SHA-256 of the request body

X-FGAI-Security-Token

Present only for temporary (STS) credentials

See Integrate with AK/SK for the canonical signing detail (canonical request, signing-key derivation, and clock-skew rules).

Scoping

Decisions are scoped to your key’s account: you can only simulate principals and resources in the account the access key belongs to. The request’s principal.account_id must be that account — a request naming any other account is refused with 403 before anything is evaluated. There is no way to probe another account.

Request

{
  "principal": {
    "account_id": "<account UUID>",
    "user_id": "<user UUID>",
    "user_type": "iam",
    "ic_session": false
  },
  "action": "licensing:Device:Read",
  "resource": "frn:<account-uuid>:licensing:device/dev-98765",
  "context": { "source_ip": "10.0.1.50" }
}
  • principal — the identity whose access you are simulating (must be in your account). Send ic_session: false for a normal IAM/service user (it is a required boolean — omitting it is rejected). Here user_type is the PDP principal-type discriminator (iam, root, or ic) that selects which evaluator DotID runs — it is not the JWT user_type claim (root / workforce) described in API authentication and JWT validation.

  • action — the operation, service:Resource:Verb (e.g. licensing:Device:Read).

  • resource — the target as a [FlexGalaxy Resource Name (FRN)](https://docs.flexgalaxy.ai/dev/dotid/frn-format/).

  • context — optional attributes evaluated by policy conditions (StringEquals, Bool, …).

Response

{
  "decision": "ALLOW",
  "reason": null,
  "matched_statement": "AllowDeviceRead"
}
  • decision — ALLOW or DENY.

  • reason — populated on DENY (e.g. EXPLICIT_DENY, IMPLICIT_DENY).

  • matched_statement — the policy statement Sid that decided an ALLOW.

The batch endpoint takes { "principal": {…}, "context": {…}, "checks": [ { "action": …, "resource": … }, … ] } — all checks share one principal and optional context — and returns { "results": [ … ] } in the same order.

Behavior

  • Fail-closed. A missing or invalid signature returns 401; an authenticated but non-HMAC caller returns 403. Absence of a matching Allow is DENY (IMPLICIT_DENY); a matching Deny always wins (EXPLICIT_DENY).

  • Permission required. Without IamPolicySimulateAccess attached to the signing service user, every call is 403 (policy-simulate-required).

  • Own account only. A principal.account_id that is not the signing key’s account is 403 and is never evaluated.

  • Rate-limited per access key. A small sustained rate with a short burst; exceeding it returns 429 with a Retry-After header. Refused requests count toward the limit too.

  • Audited. Every call is recorded with the caller (key/principal/account), the question asked, the decision, and any refusal reason.

  • Semantics match the platform. This is the same policy engine DotID uses internally; no special-cased logic exists on this surface.

See also: [Hierarchical access](https://docs.flexgalaxy.ai/dev/dotid/hierarchical-access/) for how account/OU/organization policies combine, and [FRN format](https://docs.flexgalaxy.ai/dev/dotid/frn-format/) for addressing resources.