Boundary is an AWS-focused, policy-driven JIT access broker.
It grants short-lived IAM Identity Center access from Slack, enforces approval for high-risk requests, revokes expired grants automatically, and exposes read-only audit views.
Click on any part of this image to watch the live demo:
v1pilot-ready- AWS-only scope
- Primary user interface: Slack
- Evaluates access requests against
config/access_rules.yaml - Provisions IAM Identity Center account assignments when allowed
- Supports approval workflow for sensitive permissions
- Revokes expired access on schedule (Janitor)
- Stores request lifecycle and audit evidence in DynamoDB
- Exposes read-only Audit API and Dashboard
-
Slack (
/boundary)
End-user request, approval, and notification flow. -
CLI (
src/main.py,src/janitor.py,demo.py)
Operator testing and local workflow validation. -
Web Dashboard (
/dashboard)
Read-only audit visibility.
- Slack slash command hits API Gateway
POST /webhook slack_botverifies Slack signature and enqueues request in SQSworkflow_manager:- resolves user/group identity
- evaluates policy engine
- provisions assignment (or marks pending approval/deny)
- persists request state in DynamoDB
janitor(EventBridge schedule) revokes expiredACTIVErequestsaudit_apiandaudit_dashboardread from DynamoDB with IAM auth + app RBAC/ABAC
- AWS Organization + IAM Identity Center enabled
- Slack app (slash command + interactivity)
- Terraform 1.6+
- Python 3.11+
- AWS CLI authenticated to the target account/region
cp terraform/live/envs/dev/terraform.tfvars.example terraform/live/envs/dev/terraform.tfvarsboundary_secrets.STAGING_OU_IDboundary_secrets.PROD_OU_IDboundary_secrets.AWS_SSO_START_URLboundary_secrets.AUDIT_API_PRINCIPAL_MAP(explicit caller ARNs)permission_setscontains the exact role names you will request from Slack (default keys:ReadOnlyAccess,AdministratorAccess,PowerUserAccess)
terraform -chdir=terraform/live/envs/dev init
terraform -chdir=terraform/live/envs/dev plan -out=tfplan
terraform -chdir=terraform/live/envs/dev apply tfplanterraform -chdir=terraform/live/envs/dev output -json
terraform -chdir=terraform/live/envs/dev output -raw slack_webhook_url
terraform -chdir=terraform/live/envs/dev output -raw audit_dashboard_urlNotes:
- Re-running the same
plan/applycommands is the standard way to deploy updates. - This stack packages lambdas together, so a deploy updates Boundary service lambdas in one bundle.
- Slash command Request URL → Terraform output
slack_webhook_url - Interactivity Request URL → same
/webhookendpoint
Required scopes:
chat:writeim:writeusers:readusers:read.email
Invite app to approval channel:
/invite @Boundary JIT
/boundary <AccountID> <PermissionSet> <Hours> [TicketID]
PermissionSet must match one of your configured permission_sets keys in Terraform.
Accepted forms:
/boundary 123456789012 ReadOnlyAccess 0.5
/boundary 123456789012 ReadOnlyAccess 0.02
/boundary request 111122223333 AdministratorAccess 0.5 INC-12345
/boundary 111122223333 AdministratorAccess 0.5 ticket INC-12345
Notes:
0.02hours is ~72 seconds (useful for fast revocation demos).- Approval cannot be performed by the same Slack user who submitted the request.
PYTHONPATH=src python3 demo.py --debug./boundary --help
./boundary request U12345678 123456789012 ReadOnlyAccess 0.5
./boundary status req-cli-abc123
./boundary approve req-cli-abc123 U23456789
./boundary deny req-cli-abc123 U23456789
./boundary revoke req-cli-abc123
./boundary janitor --dry-runOne-liner to use boundary like a normal installed CLI:
mkdir -p ~/.local/bin && ln -sf "$PWD/boundary" ~/.local/bin/boundary && export PATH="$HOME/.local/bin:$PATH"python3 src/main.py --helppython3 src/janitor.py --helpBase URL from Terraform output audit_api_base_url.
Endpoints:
GET /api/requestsGET /api/requests/{request_id}GET /api/metricsGET /api/exports.csv
Notes:
- API Gateway auth is
AWS_IAM - App-level RBAC/ABAC enforced via
AUDIT_API_PRINCIPAL_MAP - Deny-by-default for unmapped principals
- Wildcard principal mapping disabled unless explicitly enabled
/api/requestsand/api/exports.csvrequire one primary filter:statusaccount_idpermission_set_namerequester_slack_user_id
Base URL from Terraform output audit_dashboard_url.
Routes:
GET /dashboardGET /dashboard/requests/{request_id}
For browser use (SigV4 proxy):
python3 scripts/dashboard_proxy.py \
--dashboard-url "$(terraform -chdir=terraform/live/envs/dev output -raw audit_dashboard_url)" \
--openDashboard quick tips:
- Use
Request IDfilter for direct lookup of a single request. - Theme preference is persisted in browser storage (dark/light toggle).
- Fail-closed default deny
- Deterministic rule evaluation (ordered by YAML sequence)
- Ticket + human approval supported for sensitive roles
- Auto-revocation via scheduled janitor
- Canonicalized and validated request lifecycle states
- Read APIs authenticated and scope-filtered (RBAC + ABAC)
- Contract header/version enforced for API responses
pytest -q
terraform -chdir=terraform/live/envs/dev validate
terraform fmt -check -recursive terraformKey alarms:
boundary-dev-janitor-errorsboundary-dev-janitor-slack-notify-failures
