When an application hands its authorisation decisions to Amazon Verified Permissions, the policy store becomes the single place that decides who can do what, so whoever can change a policy, a schema or an identity source can change every access decision the application makes. Verified Permissions evaluates Cedar policies against requests from your code and returns allow or deny; it does not authenticate users, which stays with Amazon Cognito or an OpenID Connect provider. This guide covers the customer-side controls: designing the policy store and schema, turning on strict validation, configuring identity sources safely, separating policy authors from application callers in IAM, protecting the store with deletion protection and customer managed keys, and logging authorisation decisions with AWS CloudTrail. It is for application security engineers, platform teams and architects building on AWS. Cross-engine design choices are covered in the Policy-as-Code for Authorisation Guide.
This is an independent guide from NHI Mgmt Group, based on Amazon Web Services' public documentation as of November 2026. It is not sponsored or reviewed by Amazon Web Services. Product features change, so confirm settings against Amazon Web Services' current documentation.
Key takeaways
- Run production stores in Strict validation mode. With a schema in place, every new or updated policy and template is checked and rejected if it does not conform, which catches typos that would otherwise silently change access.
- Use immutable identifiers for principals and resources. AWS warns that reusing a name such as
User::"jane"passes every old grant to the new holder; use UUIDs or IdP subject IDs. - Separate policy authors from callers. Applications need only the authorisation actions on one policy store ARN; policy, schema and identity source changes belong to a pipeline role.
- Turn on data event logging. IsAuthorized and its token and batch variants are CloudTrail data events, which are not logged by default.
- Protect the store itself. Set
deletionProtectiontoENABLED(the default isDISABLED) and consider a customer managed AWS KMS key for policy data.
How identity and access work in Amazon Verified Permissions
Verified Permissions is an authorisation service only. Your application authenticates the user elsewhere, then asks the service whether a principal may perform an action on a resource, passing entities and context. The service evaluates the Cedar policies in a policy store and returns a decision with the determining policies. AWS documentation states the service currently uses Cedar version 4.12.
Core building blocks
| Component | What it does | Security decision |
|---|---|---|
| Policy store | Container for policies, templates, schema and identity sources | Isolation boundary: one store per application and environment keeps changes and IAM grants scoped |
| Schema | Cedar schema declaring namespaces, entity types with typed attributes, and actions with appliesTo principal and resource types | Optional but recommended; required for Strict validation |
| Static policy | A permit or forbid statement with principal, action and resource scope plus when and unless conditions | Use forbid for guardrails that must hold whatever is permitted |
| Policy template and template-linked policy | A policy with ?principal and ?resource placeholders, instantiated per principal and resource | Changes to a template apply to every linked policy, so treat template edits as high impact |
| Identity source | An Amazon Cognito user pool or custom OIDC provider whose tokens the store reads | Restrict to your issuer and your application's client IDs or audiences |
| Authorisation APIs | IsAuthorized, IsAuthorizedWithToken, BatchIsAuthorized, BatchIsAuthorizedWithToken | Called by the application role; logged as CloudTrail data events once enabled |
How Cedar decides
The Cedar documentation defines three rules, applied in order: if any forbid policy is satisfied the result is deny; otherwise if any permit policy is satisfied the result is allow; otherwise deny. Two properties follow. Default deny means a missing policy fails closed. Skip on error means a policy that errors at evaluation is ignored, so a forbid guardrail that errors no longer blocks. AWS gives one concrete cause: arithmetic that overflows Long or Decimal ranges makes the policy error, so a forbid may fail to block. Keep guardrail conditions simple, use has checks before reading optional attributes, and let Strict validation catch type mistakes before deployment.
Model choices such as role-based, attribute-based and relationship-based access are covered in the Authorisation Models Guide. In Verified Permissions, groups from token claims support role-based policies, entity attributes and context support attribute-based conditions, and template-linked policies suit per-resource sharing.
Admin roles and privileged access
Every change to a policy store goes through IAM-authorised API calls (or the console, CLI, SDKs, AWS CDK and CloudFormation that use them). Privileged access is therefore the set of IAM principals allowed to call management actions. The table shows a practical split; confirm exact action names in the Service Authorization Reference for Verified Permissions.
| Role | Typical actions | Scope |
|---|---|---|
| Application runtime | verifiedpermissions:IsAuthorized, IsAuthorizedWithToken and the batch variants | The single policy store ARN for that application and environment |
| Policy deployment pipeline | Create, update and delete policies and templates; PutSchema | Assumed only by the CI/CD role after review and tests |
| Identity configuration | Create, update and delete identity sources | Platform or identity team; changes are rare and high impact |
| Store administration | Create, update and delete policy stores, including validation and deletion protection settings | Small administrator group; deletion protection blocks accidental removal |
| Auditors and developers | Get and list operations; AWS managed read-only policy | Read access for review and troubleshooting |
Steps to put this in place:
- Give humans console access through AWS IAM Identity Center with MFA, as AWS recommends in the service's data protection guidance. See the AWS IAM Identity Center Guide.
- Write identity-based policies that list the policy store ARN (
arn:aws:verifiedpermissions::ACCOUNT:policy-store/ID) as the resource rather than*. - Remove direct policy-editing rights from developers in production; changes flow from source control through the pipeline role.
- Use a service control policy or permissions boundary to stop anyone but the store administrators from changing
validationSettingsordeletionProtection. - Validate grants with the IAM Access Analyzer Guide and the patterns in the AWS IAM Policies and Roles Guide.
Integrations, API tokens and service accounts
The calling application is itself a non-human identity: a Lambda function role, an ECS task role or an API Gateway authoriser. Its credentials come from IAM roles, so there are no long-lived keys to store. Give each service its own role, and avoid IAM user access keys for callers.
Identity sources
An identity source tells the policy store how to read tokens your application passes to IsAuthorizedWithToken. AWS documents that the service makes decisions from token claims and does not contact the IdP directly. Two types are supported: Amazon Cognito user pools, and custom OIDC providers whose issuer is an https:// URL serving .well-known/openid-configuration.
- Token choice: with ID tokens, attribute claims become principal attributes; with access tokens, claims become context. For OIDC sources,
tokenSelectionchooses one:identityTokenOnlywith the client IDs to accept, oraccessTokenOnlywith the audiences to accept. List only your application's values. - Principal and groups: the token's user identity maps to the principal ID, optionally with an
entityIdPrefixso policies readMyCorp::User::"MyOIDCProvider|sub";groupConfigurationmaps a claim such asgroupsto a group entity type for role-based policies. - Use the subject, not the email: map principals from an immutable claim such as
sub, matching AWS's advice to use unique, non-reusable identifiers. - Short token lifetimes: decisions use claims as issued, so a removed group membership persists until the token expires. Keep access token lifetimes short at the IdP; see the Amazon Cognito Security Guide and the JWT Security Guide.
Passing entities with IsAuthorized
Where you call IsAuthorized directly, your application supplies the principal, its attributes and group parents in the entities list. That data is trusted as given. Build it server-side from your own data stores, never from request parameters the client controls, and keep sensitive values out of action names, policy store descriptions and tags, which AWS warns may appear in billing or diagnostic logs.
Choosing the call pattern
| Situation | Better fit | Why |
|---|---|---|
| Users sign in through Cognito or one OIDC provider, and group claims drive roles | IsAuthorizedWithToken with an identity source | The store reads principal and groups from the token, so application code cannot alter them |
| Principals come from several directories, or attributes live in your database | IsAuthorized with server-built entities | You control exactly which attributes are asserted, at the cost of building them safely |
| A page or list needs decisions for many resources at once | The batch variants | Fewer calls; the same logging and IAM rules apply |
A small team with one application can start with one store per environment and a single pipeline role. A large organisation with many applications or tenants benefits from separate stores per application, a shared schema convention, and a central platform team that owns identity sources while product teams own their policies.
Logging and detection
CloudTrail records Verified Permissions in two categories. Control plane operations such as CreatePolicyStore, PutSchema, CreatePolicy, CreatePolicyTemplate, CreateIdentitySource and DeleteIdentitySource are management events, logged by a trail by default. IsAuthorized, IsAuthorizedWithToken, BatchIsAuthorized and BatchIsAuthorizedWithToken are data events (eventCategory: Data), which AWS states are not logged by default; add them to a trail or CloudTrail Lake event data store using the resource type AWS::VerifiedPermissions::PolicyStore. Data events carry a cost, so scope selectors to production stores. See the AWS CloudTrail Guide.
| Signal | Event | What to do |
|---|---|---|
| Policy, template or schema change outside the pipeline role | CreatePolicy, UpdatePolicy, CreatePolicyTemplate, PutSchema | Alert immediately; compare with source control |
| Validation mode switched to OFF or deletion protection disabled | UpdatePolicyStore | High-severity alert in production |
| Identity source added, changed or removed | CreateIdentitySource, UpdateIdentitySource, DeleteIdentitySource | Confirm issuer and client IDs against the approved list |
| Spike in deny decisions for one principal | IsAuthorized data events | Possible probing or a broken deployment |
| Authorisation calls from an unexpected role or account | Data events, userIdentity | Review IAM grants on the store |
Metrics that show the controls work: share of production stores in Strict mode with deletion protection (target 100%); share of policy changes made by the pipeline role (target 100%); mean time from an out-of-band change to alert; number of IAM principals with management actions on each store; and percentage of principals mapped from immutable identifiers.
Hardening baseline
A phased rollout keeps authorisation changes testable and reversible.
- Design: create one policy store per application and environment, define the Cedar schema with namespaces, entity types and actions, and store schema and policies in version control.
- Develop: AWS suggests validation off during early development; write unit tests for allow and deny cases with the Cedar tooling or a test policy store.
- Test: switch the test store to Strict (
update-policy-store --validation-settings mode=STRICT, only after a schema exists, or every policy fails validation). Replay representative requests and compare decisions with the current in-code logic. - Shadow: call Verified Permissions alongside existing checks, log mismatches, and fix policies before enforcing.
- Enforce: make the service authoritative, with a reviewed fail-closed behaviour if the call errors or times out.
- Protect: enable
deletionProtection, setencryptionSettingswith a customer managed KMS key where policy data is sensitive, and turn on CloudTrail data events. - Roll back: redeploy the previous tagged policy set from source control through the pipeline; keep the old in-code check available behind a flag until the service has run cleanly for an agreed period.
| Framework | Reference | Verified Permissions control |
|---|---|---|
| NIST SP 800-53 Rev 5 | AC-3 Access Enforcement | Cedar policies evaluated per request, default deny |
| NIST SP 800-53 Rev 5 | AC-6 Least Privilege | Scoped IAM for callers and authors; narrow permit policies |
| NIST SP 800-53 Rev 5 | CM-3 Configuration Change Control | Pipeline-only policy changes, Strict validation |
| NIST SP 800-53 Rev 5 | AU-2, AU-12 | CloudTrail management and data events |
| OWASP ASVS 5.0 | V8.1.1 | Documented authorisation rules, held as a reviewed Cedar schema and policy set |
| ISO/IEC 27001:2022 Annex A | A.5.15, A.8.3, A.8.15 | Access control, information access restriction, logging |
Common misconfigurations
- Validation left off in production: a misspelt attribute in a
whenclause means the policy never matches or errors, quietly changing access. Run production in Strict. - Mutable principal IDs: keying principals on usernames or email addresses lets a reassigned name inherit old grants.
- Guardrails that can error: a
forbidreading an optional attribute without ahascheck is skipped when the attribute is missing, so the deny never applies. - Wildcard IAM on callers: an application role with
verifiedpermissions:*can rewrite the policies it is checked against. - Client-supplied entities: passing group or role attributes from the request into
IsAuthorizedlets callers grant themselves access. - No decision logging: data events not enabled, so there is no record of who was allowed what during an investigation.
Practitioner checklist
- Create one policy store per application and environment, with schema and policies in version control.
- Set production stores to Strict validation after the schema is in place.
- Enable deletion protection and choose AWS managed or customer managed KMS encryption deliberately.
- Map principals from immutable identifiers such as
subor UUIDs. - Restrict identity sources to your issuer and your application's client IDs or audiences; keep token lifetimes short.
- Grant application roles only authorisation actions on their own store ARN.
- Route all policy, template and schema changes through a reviewed pipeline with allow and deny tests.
- Write
forbidguardrails that cannot error, withhaschecks on optional attributes. - Enable CloudTrail data events for production stores and alert on management changes.
- Review IAM grants and identity sources on each store every quarter.
Standards and references
- AWS: What is Amazon Verified Permissions?
- AWS: Verified Permissions identity sources
- AWS: Policy validation mode
- AWS: Policy templates and template-linked policies
- AWS: Data protection in Amazon Verified Permissions
- AWS: Logging Verified Permissions API calls with CloudTrail
- AWS: CreatePolicyStore API reference
- Cedar: Authorization decisions
Related NHI Mgmt Group resources: Policy-as-Code for Authorisation Guide · Authorisation Models Guide · Amazon Cognito Security Guide · AWS CloudTrail Guide · Fine-Grained Authorisation Guide