Skip to main content
This guide will walk you through deploying the complete demo in under 15 minutes.

Step 1: Create the Policy Store

AWS Verified Permissions stores your authorization policies in a Policy Store. You’ll create this manually in the AWS Console.
1

Open AWS Verified Permissions console

Navigate to the AWS Console and search for “Verified Permissions” in the services search bar.
Make sure you’re in the same AWS region where you’ll deploy the Lambda functions (e.g., us-west-2).
2

Create a new Policy Store

Click “Create policy store”
Select “Empty policy store” - do NOT use the “Guided setup” option. The guided setup creates a different schema structure.
3

Configure the Policy Store

  • Policy store name: FinancialDocsStore
  • Validation mode: Schema-based (default)
  • Click “Create”
4

Copy the Policy Store ID

After creation, you’ll see the Policy Store dashboard. Copy the Policy Store ID (format: PSEXAMPLEabcdefg12345678).
Save this ID - you’ll need it in Step 3 for the SAM deployment.

Step 2: Define the schema

The schema defines the structure of your entities (users, resources) and their attributes.
1

Open the Schema editor

In your Policy Store dashboard, navigate to SchemaEdit
2

Replace with the FinancialApp schema

Delete any existing content and paste this complete schema:
{
    "FinancialApp": {
        "entityTypes": {
            "User": {
                "shape": {
                    "type": "Record",
                    "attributes": {
                        "department": {
                            "type": "String",
                            "required": true
                        },
                        "clearance_level": {
                            "type": "Long",
                            "required": true
                        }
                    }
                },
                "memberOfTypes": ["Role"]
            },
            "Document": {
                "shape": {
                    "type": "Record",
                    "attributes": {
                        "classification": {
                            "type": "String",
                            "required": true
                        },
                        "department": {
                            "type": "String",
                            "required": true
                        }
                    }
                }
            },
            "Role": {
                "memberOfTypes": []
            }
        },
        "actions": {
            "Read": {
                "appliesTo": {
                    "principalTypes": ["User"],
                    "resourceTypes": ["Document"]
                }
            },
            "Edit": {
                "appliesTo": {
                    "principalTypes": ["User"],
                    "resourceTypes": ["Document"]
                }
            },
            "Delete": {
                "appliesTo": {
                    "principalTypes": ["User"],
                    "resourceTypes": ["Document"]
                }
            }
        }
    }
}
The "memberOfTypes": ["Role"] field in the User entity is critical. It tells AVP that a User can belong to a Role, which is necessary for Cedar to evaluate principal in Role::"Analyst".
3

Save the schema

Click “Save changes”The console will validate your schema. If there are any errors, double-check that you copied the entire JSON correctly.

Step 3: Build and deploy with SAM

Now you’ll use AWS SAM to build and deploy the Lambda functions and API Gateway.
1

Navigate to the project directory

cd ~/workspace/source/
2

Build the SAM application

sam build
This command packages your Lambda functions and their dependencies. You should see output like:
Build Succeeded

Built Artifacts  : .aws-sam/build
Built Template   : .aws-sam/build/template.yaml
3

Deploy with guided mode

sam deploy --guided
SAM will ask you several configuration questions. Use these answers:
QuestionYour answer
Stack Nameavp-demo
AWS Regionus-west-2 (or your preferred region)
Parameter PolicyStoreIdPaste the ID from Step 1
Parameter AnthropicApiKeyYour sk-ant-... key (or placeholder)
Confirm changes before deployy
Allow SAM CLI to create IAM rolesy
Disable rollbackn
CheckAccessFunction has no authenticationy
GetUsersFunction has no authenticationy
AgentFunction has no authenticationy
Save arguments to configuration filey
SAM configuration filePress ENTER (uses samconfig.toml)
SAM configuration environmentPress ENTER (uses default)
Deploy this changeset?y
If you don’t plan to use the AI agent, enter placeholder as the Anthropic API key. The main demo will work without it.
4

Copy the API URL

After successful deployment, SAM will display the outputs:
Outputs
-------
ApiUrl        = https://abc123xyz.execute-api.us-west-2.amazonaws.com/prod
AgentEndpoint = https://abc123xyz.execute-api.us-west-2.amazonaws.com/prod/agent
Copy the ApiUrl value - you’ll need it in the next step.

Step 4: Configure the frontend

The frontend HTML files need to know your API Gateway URL.
1

Open index.html

Open ~/workspace/source/frontend/index.html in your code editor.
2

Update the API URL

Find line ~837 and replace the placeholder URL with your API URL from Step 3:
const API_BASE_URL = "https://abc123xyz.execute-api.us-west-2.amazonaws.com/prod";
The URL must end with /prod - do not add any additional paths like /check-access.
3

Update avp-agent.html (if using AI agent)

If you provided an Anthropic API key, also update ~/workspace/source/frontend/avp-agent.html at line ~237:
const API_BASE = "https://abc123xyz.execute-api.us-west-2.amazonaws.com/prod";

Step 5: Run the demo locally

Start a local web server to access the frontend.
1

Navigate to the frontend directory

cd ~/workspace/source/frontend
2

Start the web server

python3 -m http.server 8000
You should see:
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...
3

Open in your browser

Navigate to one of these URLs:
URLDescription
http://localhost:8000/index.htmlMain AVP demo lab
http://localhost:8000/avp-agent.htmlAI agent with natural language
Do NOT open the files using file:// protocol. The browser will block API calls due to CORS. Always use http://localhost:8000.

Demo walkthrough

Now that everything is deployed, let’s run through the core demo scenarios.

Act 1: Zero Trust (deny by default)

1

Enter your Policy Store ID

In the web interface, paste your Policy Store ID in the configuration field.
2

Test Alice's access

  • Select user: Alice Garcia (Analyst, Finance)
  • Select resource: Q4-Report-2024
  • Select action: Read
  • Click Check Access
Result: 🚫 DENYThis demonstrates Zero Trust: even though Alice has valid credentials and works in Finance (same department as the document), AVP denies access because no policy explicitly permits it.

Act 2: Cedar policy in action

1

Create your first policy

Go to AWS Console → Verified Permissions → Your Policy Store → PoliciesCreateStatic policyPolicy name: AllowAnalystReadOwnDepartment
permit (
  principal in FinancialApp::Role::"Analyst",
  action == FinancialApp::Action::"Read",
  resource
)
when {
  principal.department == resource.department
};
This policy allows users in the Analyst role to Read documents, but only if the user’s department matches the document’s department (ABAC condition).
2

Test Alice again

Repeat the same request:
  • User: Alice Garcia
  • Resource: Q4-Report-2024
  • Action: Read
Result:ALLOW
You didn’t change any code. You didn’t redeploy. You just added a Cedar policy, and it took effect immediately.

Act 3: Attribute-based access control

1

Test cross-department access

  • User: Carol Mendez (Auditor, HR)
  • Resource: Q4-Report-2024 (Finance department)
  • Action: Read
Result: 🚫 DENYCarol is denied because her department (HR) doesn’t match the document’s department (Finance), even though she’s an Auditor.
2

Create an Auditor policy

Create a new policy that allows Auditors to read any document:
permit (
  principal in FinancialApp::Role::"Auditor",
  action == FinancialApp::Action::"Read",
  resource
);
3

Test Carol again

Same request as before:Result:ALLOWNow Carol can access the Finance document because her Auditor role grants cross-department read access.

Act 4: Forbid overrides permit

1

Add a forbid policy

Create this policy to block Auditors from editing or deleting:
forbid (
  principal in FinancialApp::Role::"Auditor",
  action in [FinancialApp::Action::"Edit", FinancialApp::Action::"Delete"],
  resource
);
2

Test Carol's edit access

  • User: Carol Mendez
  • Resource: Q4-Report-2024
  • Action: Edit
Result: 🚫 DENYEven if you created a permit policy for Edit, the forbid would win. In Cedar, forbid always takes precedence over permit.

Act 5 (Bonus): AI agent

This requires an Anthropic API key. Skip this if you used placeholder during deployment.
1

Open the AI agent interface

Navigate to http://localhost:8000/avp-agent.html
2

Ask a natural language question

Type in the chat:
“Check access for all users to Q4-Report-2024 for Read action”
The AI agent will:
  1. Understand your request
  2. Make multiple calls to the AVP check_avp_access tool
  3. Summarize the results in natural language
All without you having to specify the exact API calls or structure.

Understanding the Lambda code

The core authorization logic lives in lambda/app.py. Here’s how it works:
avp_response = avp_client.is_authorized(
    policyStoreId=POLICY_STORE_ID,
    principal={
        "entityType": "FinancialApp::User",
        "entityId":    user_id
    },
    action={
        "actionType": "FinancialApp::Action",
        "actionId":    action_id
    },
    resource={
        "entityType": "FinancialApp::Document",
        "entityId":    resource_id
    },
    entities={
        "entityList": build_entity_list(user_id, resource_id)
    }
)

decision = avp_response["decision"]  # "ALLOW" or "DENY"
The build_entity_list function provides AVP with the full context needed to evaluate Cedar policies, including user attributes, role membership, and resource properties.

Next steps

Learn Cedar policy language

Practice writing Cedar policies in the interactive playground

AWS Verified Permissions docs

Explore the official AVP documentation

AVP Workshop

Take the official AWS workshop on Verified Permissions

Cedar on GitHub

Explore the open-source Cedar policy engine

Cleanup

When you’re done with the demo, remove all AWS resources to avoid charges:
# Delete the CloudFormation stack (Lambdas and API Gateway)
sam delete --stack-name avp-demo
Then manually delete the Policy Store:
  1. Go to AWS Console → Verified Permissions
  2. Select your FinancialDocsStore
  3. Click Delete
  4. Confirm deletion
The demo uses serverless resources that scale to zero when not in use, so costs are minimal. However, it’s good practice to clean up resources you’re not using.

Build docs developers (and LLMs) love