đ What is EmpowerNow?
EmpowerNow is an enterprise-grade Identity, Authorization, and Workflow Automation platform designed for zero-trust security. It provides identity management, fine-grained access control, and extensible workflow capabilities.
Identity Management
OIDC-compliant Identity Provider with federation, WebAuthn, and continuous access evaluation.
Policy-Based Authorization
AuthZEN 1.1 compliant PDP with hierarchical YAML policies and rich decision explanations.
Workflow Automation
Orchestration with CRUD operations, approval workflows, connectors, and integrations.
Membership Graph
Neo4j-powered role hierarchies, group management, and relationship-based access control.
đī¸ System Architecture
The platform follows a layered microservices architecture with clear separation of concerns. The user-facing surface is a single Experience app shell; product capabilities ship as governed ESM plugins loaded dynamically from the BFF (not separate frontends per service).
đ§ Core Services
Quick reference for the main services:
IdP (Identity Provider)
OIDC/OAuth2 authentication, token issuance, WebAuthn, CAEP, DPoP support.
idp.self :8002PDP (Policy Decision Point)
AuthZEN 1.1 authorization, YAML policies, PIPs, decision explanations.
pdp.self :8001Membership Service
Neo4j role hierarchies, user assignments, relationship-based access.
membership.self :8003CRUD Service
Workflow engine, approval flows, connectors, automation.
crud.self :8000BFF Gateway
API gateway, OAuth proxy, session management, SPA hosting.
api.self :8000Traefik
Reverse proxy, TLS termination, routing, ForwardAuth.
traefik.self :443đ Quick Start Commands
Image-First Approach
Only ServiceConfigs is required to run the full stack! Pre-built images are pulled automatically.
1. Clone & Navigate
From a folder of your choice (this will become your project root, e.g. EmpowerNow):
# Use the deployment directory your organization provides (layout may differ)
cd <your-deployment-root>/DeploymentThe actual on-disk directory is serviceconfigs (lowercase). On macOS (case-insensitive) both casings work. On Linux (case-sensitive), you must use the exact casing: serviceconfigs/Deployment.
2. Authenticate to ACR (only when using pre-built images)
If you run without --build, images are pulled from eidci.azurecr.io. Run az acr login --name eidci (or docker login eidci.azurecr.io with credentials from Azure Portal â eidci â Access keys). With --build, services are built locally â ACR login is not required.
3. Start Core Services
# Start core services (from ServiceConfigs/Deployment)
docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --build
# View logs
docker compose logs -f idp pdp bff
# Check status
docker compose ps4. First-Time BFF Setup
# If BFF is crashing, generate DCR token (run from ServiceConfigs/Deployment)
./scripts/create-idp-admin-jwt-secret.ps1
# Then restart
docker compose -f docker-compose.yml -f docker-compose-build.yml --profile core up -d --buildđĻ Docker Profiles
Run only what you need using profiles:
core Core Services
monitoring Monitoring
analytics Analytics
security Security
tools Dev Tools
ldap LDAP
mcp MCP Gateway
# Core only (minimal resources)
docker compose --profile core up -d
# Core + monitoring
docker compose --profile core --profile monitoring up -d
# Core + dev tools (pgAdmin, Dozzle)
docker compose --profile core --profile tools up -d
# Full stack
docker compose --profile core --profile security --profile monitoring --profile analytics up -d
# With MCP Gateway
docker compose --profile core --profile mcp up -d
# Stop everything
docker compose --profile core downđ Service Dependencies
Understanding how services depend on each other is critical for troubleshooting:
:5432"] DB --> Redis["⥠Redis
:6379"] DB --> OpenBao["đ OpenBao
:8200"] DB --> Neo4j["đˇ Neo4j
:7687"] OpenBao --> CrudService["âī¸ CrudService
:8000"] Neo4j --> CrudService CrudService --> IdP["đ IdP
:8002"] CrudService --> Membership["đĨ Membership
:8003"] Redis --> IdP IdP --> PDP["đĄī¸ PDP
:8001"] Membership --> PDP PDP --> BFF["đ BFF
:8000"] style DB fill:#f59e0b22,stroke:#f59e0b style Redis fill:#f43f5e22,stroke:#f43f5e style OpenBao fill:#f43f5e22,stroke:#f43f5e style Neo4j fill:#f59e0b22,stroke:#f59e0b style CrudService fill:#10b98122,stroke:#10b981 style IdP fill:#3b82f622,stroke:#3b82f6 style Membership fill:#10b98122,stroke:#10b981 style PDP fill:#a855f722,stroke:#a855f7 style BFF fill:#00d9ff22,stroke:#00d9ff
Key Dependencies
PostgreSQL â Everything
Stores users, OAuth clients, policies, business data. All services wait for DB.
CrudService â IdP
IdP stores DCR secrets via CrudService's Secrets API (not directly to Vault!).
IdP â BFF
BFF registers itself with IdP using DCR on startup. If IdP is down, BFF crashes.
IdP â PDP
PDP introspects tokens with IdP. Authorization requires valid identity.
⥠DCR Bootstrap Flow
Dynamic Client Registration (DCR) is how BFF gets its OAuth credentials on startup:
First-Time BFF Bootstrap
On first run, BFF will crash because it needs an admin JWT. This is expected! Run the script below to fix it.
Fix BFF Bootstrap (First Time Only)
# Step 1: Generate admin JWT (run from ServiceConfigs/Deployment)
./scripts/create-idp-admin-jwt-secret.ps1
# Step 2: Restart BFF
docker compose up -d bff
# Step 3: Verify BFF is healthy
docker ps --filter "name=bff"
# Should show: "Up X seconds (healthy)"DCR Troubleshooting
â "DCR bootstrap failed"
Missing or expired admin JWT
Fix: Run create-idp-admin-jwt-secret.ps1â "Name or service not known"
CrudService not running (IdP can't store secrets)
Fix: docker compose up -d crud-serviceâ "Vault is sealed"
OpenBao not initialized
Fix: docker compose up -d openbao-initâ "Client not found"
Database migrations didn't run
Fix: docker compose up -d idp-alembicđ Key URLs
After services are running:
đ¨ Experience Portal
Main user portal with all plugins (Identity, AuthZ, Workflows)
https://experience.self.empowernow.aiđ IdP API
Direct API access for identity management
https://idp.self.empowernow.ai/apiđĄī¸ PDP API
Direct API for policy evaluation
https://pdp.self.empowernow.ai/apiđ pgAdmin
Database inspection (tools profile)
https://pgadmin.self.empowernow.aiUI Consolidation
Identity management and AuthZ configuration are now Experience Portal plugins. Use the Experience Portal for all UI-based administration, or the APIs documented below for automation.
Self-Signed Certificates
First visit may show certificate warning. Click "Advanced" â "Proceed" to accept the local dev certificate.
đ Test Credentials
Use these pre-seeded credentials for testing and development:
Test User Account
Standard test user for authentication flows and API testing.
testpasswordOAuth Test Client
Pre-configured OAuth client for client_credentials and authorization_code flows.
service-clientsecret1Quick Token Test
Get an access token using the password grant:
curl -k -X POST https://idp.self.empowernow.ai/api/oidc/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=service-client" \
-d "client_secret=secret1" \
-d "username=test" \
-d "password=password" \
-d "scope=openid profile email"đ§ API Operations
Use these API examples to manage users and clients programmatically. Perfect for automation, testing, or when the Experience Portal is unavailable.
Step 1: Get an Admin Access Token
First, obtain a token with admin scopes:
curl -k -X POST https://idp.self.empowernow.ai/api/oidc/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "grant_type=password" \
-d "client_id=service-client" \
-d "client_secret=secret1" \
-d "username=admin_user" \
-d "password=password" \
-d "scope=openid profile user:read user:write admin:users"Save Your Token
Copy the access_token from the response. You'll need it for all subsequent API calls.
Step 2: Create a New User
Use the IdP Users API to create a new user account:
curl -k -X POST https://idp.self.empowernow.ai/api/v1/users \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"email": "jane.smith@example.com",
"email_verified": true,
"name": "Jane Smith",
"given_name": "Jane",
"family_name": "Smith",
"password": "SecurePass123!",
"roles": ["user"]
}'Password Requirements
Passwords must be 8+ characters with at least: 1 uppercase, 1 lowercase, 1 number, and 1 special character (@$!%*?&).
Step 3: List Users
Verify the user was created:
curl -k -X GET "https://idp.self.empowernow.ai/api/v1/users?limit=10" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"Step 4: Get a Specific User
Retrieve details for a specific user by their ID (username part of email):
curl -k -X GET https://idp.self.empowernow.ai/api/v1/users/jane.smith \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"đ Quick Try: PowerShell One-Liner
Run this in PowerShell to create a user in one go:
# Get token and create user in one script
$tokenResponse = Invoke-RestMethod -Uri "https://idp.self.empowernow.ai/api/oidc/token" `
-Method POST -ContentType "application/x-www-form-urlencoded" `
-Body "grant_type=password&client_id=service-client&client_secret=secret1&username=admin_user&password=password&scope=openid user:write" `
-SkipCertificateCheck
$token = $tokenResponse.access_token
$newUser = @{
email = "newdev@example.com"
email_verified = $true
name = "New Developer"
given_name = "New"
family_name = "Developer"
password = "DevPass123!"
roles = @("user", "testrole")
} | ConvertTo-Json
Invoke-RestMethod -Uri "https://idp.self.empowernow.ai/api/v1/users" `
-Method POST -ContentType "application/json" `
-Headers @{ Authorization = "Bearer $token" } `
-Body $newUser -SkipCertificateCheckExpected Response
You should see a JSON response with the created user's details including user_id, email, name, and roles.
API Quick Reference
List Users
GET /api/v1/users
Create User
POST /api/v1/users
Get User
GET /api/v1/users/{id}
Update User
PUT /api/v1/users/{id}
đ What's Next?
Now that you have the big picture, start the detailed training:
Ready to Begin!
Proceed to Day 01: Platform Architecture for a deep dive, or Day 02: Environment Setup to set up your development environment first.