Skip to content

Commit fab1838

Browse files
Feat: add traction tenant mode for secure webhook registration (#926)
* feat: implement tenant api fallback for webhook registration Signed-off-by: Yuki I <omoge.real@gmail.com> * feat: add traction tenant mode for secure webhook registration Signed-off-by: Yuki I <omoge.real@gmail.com> * feat: add traction tenant mode for secure webhook registration Signed-off-by: Yuki I <omoge.real@gmail.com> * test: improve coverage for webhook utils and config error handling Signed-off-by: Yuki I <omoge.real@gmail.com> * test: fix traction config test failures by setting instance attributes Signed-off-by: Yuki I <omoge.real@gmail.com> * feat: unify multi-tenant config and add traction mode support Signed-off-by: Yuki I <omoge.real@gmail.com> * feat: unify multi-tenant config and add traction mode support Signed-off-by: Yuki I <omoge.real@gmail.com> * refactor: centralize config in .env and clean manage script Signed-off-by: Yuki I <omoge.real@gmail.com> * fix: address code review feedback on traction mode Signed-off-by: Yuki I <omoge.real@gmail.com> * fix: implement token TTL caching and update deprecation docs Signed-off-by: Yuki I <omoge.real@gmail.com> * fix: implement token TTL caching and update deprecation docs Signed-off-by: Yuki I <omoge.real@gmail.com> * feat: make token cache TTL configurable via env var Signed-off-by: Yuki I <omoge.real@gmail.com> * fix: add validation for token cache TTL Signed-off-by: Yuki I <omoge.real@gmail.com> --------- Signed-off-by: Yuki I <omoge.real@gmail.com>
1 parent 01a9c51 commit fab1838

File tree

14 files changed

+1139
-270
lines changed

14 files changed

+1139
-270
lines changed

docker/.env.example

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
############################################
2+
# Global / Logging
3+
############################################
4+
COMPOSE_PROJECT_NAME=vc-authn
5+
LOG_LEVEL=DEBUG
6+
LOG_WITH_JSON=false
7+
DEBUGGER=false
8+
9+
############################################
10+
# Controller Database (Mongo)
11+
############################################
12+
MONGODB_HOST=controller-db
13+
MONGODB_PORT=27017
14+
MONGODB_NAME=oidccontroller
15+
OIDC_CONTROLLER_DB_USER=changeme
16+
OIDC_CONTROLLER_DB_USER_PWD=changeme
17+
18+
19+
############################################
20+
# OIDC Controller Service
21+
############################################
22+
CONTROLLER_SERVICE_PORT=5000
23+
24+
# Public URLs
25+
CONTROLLER_URL=https://your-public-url.example.com
26+
CONTROLLER_WEB_HOOK_URL=https://your-public-url.example.com/webhooks
27+
CONTROLLER_API_KEY=
28+
29+
# Controller Behavior
30+
CONTROLLER_CAMERA_REDIRECT_URL=wallet_howto
31+
CONTROLLER_PRESENTATION_EXPIRE_TIME=300
32+
CONTROLLER_PRESENTATION_CLEANUP_TIME=86400
33+
CONTROLLER_PRESENTATION_RECORD_RETENTION_HOURS=1
34+
CONTROLLER_CLEANUP_MAX_PRESENTATION_RECORDS=1000
35+
CONTROLLER_CLEANUP_MAX_CONNECTIONS=2000
36+
37+
# Configuration Files & Paths
38+
CONTROLLER_SESSION_TIMEOUT_CONFIG_FILE=/etc/controller-config/sessiontimeout.json
39+
CONTROLLER_VARIABLE_SUBSTITUTION_OVERRIDE=/etc/controller-config/user_variable_substitution.py
40+
CONTROLLER_TEMPLATE_DIR=/app/controller-config/templates
41+
42+
# Verification Options
43+
INVITATION_LABEL="VC-AuthN"
44+
SET_NON_REVOKED=true
45+
ACAPY_PROOF_FORMAT=anoncreds
46+
USE_OOB_LOCAL_DID_SERVICE=true
47+
USE_CONNECTION_BASED_VERIFICATION=true
48+
USE_URL_DEEP_LINK=false
49+
WALLET_DEEP_LINK_PREFIX=bcwallet://aries_proof-request
50+
51+
# Scaling & Caching
52+
CONTROLLER_REPLICAS=3
53+
USE_REDIS_ADAPTER=false
54+
REDIS_HOST=redis
55+
REDIS_PORT=6379
56+
REDIS_PASSWORD=
57+
REDIS_DB=0
58+
59+
60+
############################################
61+
# ACA-Py Agent
62+
############################################
63+
AGENT_HOST=localhost
64+
AGENT_NAME="VC-AuthN Agent"
65+
66+
AGENT_HTTP_PORT=8030
67+
AGENT_ADMIN_PORT=8077
68+
69+
# Traction / ACA-Py admin endpoints
70+
AGENT_ADMIN_URL=https://traction-admin.example.com
71+
AGENT_ENDPOINT=https://traction-acapy-endpoint.example.com
72+
73+
AGENT_ADMIN_API_KEY=changeme
74+
AGENT_GENESIS_URL=https://test.bcovrin.vonx.io/genesis
75+
AGENT_WALLET_SEED=your-32-char-seed-here-00000000000000
76+
77+
78+
########################################################
79+
# ACA-Py Wallet / Tenant Identity
80+
#
81+
# When AGENT_TENANT_MODE=multi:
82+
# ACAPY_TENANT_WALLET_ID = Wallet ID
83+
# ACAPY_TENANT_WALLET_KEY = Wallet Key
84+
#
85+
# When AGENT_TENANT_MODE=traction:
86+
# ACAPY_TENANT_WALLET_ID = Traction Tenant ID
87+
# ACAPY_TENANT_WALLET_KEY = Traction Tenant API Key
88+
########################################################
89+
AGENT_TENANT_MODE=traction
90+
91+
ACAPY_TENANT_WALLET_ID=your-tenant-id-here
92+
ACAPY_TENANT_WALLET_KEY=your-tenant-key-here
93+
94+
# Cache TTL for tenant tokens in seconds (default: 3600)
95+
ACAPY_TOKEN_CACHE_TTL=3600
96+
97+
# Legacy (ignored when ACAPY_TENANT_* is set)
98+
MT_ACAPY_WALLET_ID=legacy-wallet-id
99+
MT_ACAPY_WALLET_KEY=legacy-wallet-key
100+
101+
102+
##########################################################
103+
# ACA-Py Single-Tenant Settings (AGENT_TENANT_MODE=single)
104+
##########################################################
105+
ST_ACAPY_ADMIN_API_KEY_NAME=
106+
ST_ACAPY_ADMIN_API_KEY=
107+
108+
109+
##############################
110+
# Wallet Database (PostgreSQL)
111+
##############################
112+
WALLET_TYPE=postgres_storage
113+
WALLET_ENCRYPTION_KEY=key
114+
POSTGRESQL_WALLET_HOST=wallet-db
115+
POSTGRESQL_WALLET_PORT=5432
116+
POSTGRESQL_WALLET_DATABASE=wallet_db
117+
POSTGRESQL_WALLET_USER=walletuser
118+
POSTGRESQL_WALLET_PASSWORD=walletpassword
119+
120+
121+
############################################
122+
# OIDC Client
123+
############################################
124+
OIDC_CLIENT_ID=your-client-id
125+
OIDC_CLIENT_NAME="Your Application Name"
126+
OIDC_CLIENT_REDIRECT_URI=https://your-redirect-url.example.com
127+
OIDC_CLIENT_SECRET=your-client-secret
128+
129+
130+
############################################
131+
# Keycloak Database
132+
############################################
133+
KEYCLOAK_DB_NAME=keycloak
134+
KEYCLOAK_DB_USER=keycloak
135+
KEYCLOAK_DB_PASSWORD=changeme
136+
137+
138+
############################################
139+
# Keycloak Service
140+
############################################
141+
KEYCLOAK_DB_VENDOR=postgres
142+
KEYCLOAK_DB_ADDR=keycloak-db
143+
KEYCLOAK_USER=admin
144+
KEYCLOAK_PASSWORD=admin
145+
KEYCLOAK_LOGLEVEL=WARN
146+
KEYCLOAK_ROOT_LOGLEVEL=WARN

docker/docker-compose.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,11 @@ services:
4949
- ACAPY_TENANCY=${AGENT_TENANT_MODE}
5050
- ACAPY_AGENT_URL=${AGENT_ENDPOINT}
5151
- ACAPY_ADMIN_URL=${AGENT_ADMIN_URL}
52+
# Unified Tenant / Wallet Configuration
53+
- ACAPY_TENANT_WALLET_ID=${ACAPY_TENANT_WALLET_ID}
54+
- ACAPY_TENANT_WALLET_KEY=${ACAPY_TENANT_WALLET_KEY}
55+
- ACAPY_TOKEN_CACHE_TTL=3600
56+
# Legacy variables (passed for backward compatibility)
5257
- MT_ACAPY_WALLET_ID=${MT_ACAPY_WALLET_ID}
5358
- MT_ACAPY_WALLET_KEY=${MT_ACAPY_WALLET_KEY}
5459
- ST_ACAPY_ADMIN_API_KEY=${AGENT_ADMIN_API_KEY}

docker/manage

Lines changed: 15 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -169,112 +169,25 @@ configureEnvironment() {
169169
esac
170170
done
171171

172-
## global
173-
export COMPOSE_PROJECT_NAME="${COMPOSE_PROJECT_NAME:-vc-authn}"
174-
export LOG_LEVEL=${LOG_LEVEL:-"DEBUG"}
175-
176-
# controller-db
177-
export MONGODB_HOST="controller-db"
178-
export MONGODB_PORT="27017"
179-
export MONGODB_NAME="oidccontroller"
180-
export OIDC_CONTROLLER_DB_USER="oidccontrolleruser"
181-
export OIDC_CONTROLLER_DB_USER_PWD="oidccontrollerpass"
182-
183-
184-
# controller
185-
export CONTROLLER_SERVICE_PORT=${CONTROLLER_SERVICE_PORT:-5000}
186-
export CONTROLLER_URL="${CONTROLLER_URL:-http://controller:5000}"
187-
export CONTROLLER_WEB_HOOK_URL=${CONTROLLER_WEB_HOOK_URL:-${CONTROLLER_URL}/webhooks}
188-
if [ ! -z "${CONTROLLER_API_KEY}" ]; then
189-
CONTROLLER_WEB_HOOK_URL="${CONTROLLER_WEB_HOOK_URL}#${CONTROLLER_API_KEY}"
172+
# Controller Webhook URL: Append API Key if present
173+
if [ ! -z "${CONTROLLER_API_KEY}" ] && [[ "${CONTROLLER_WEB_HOOK_URL}" != *"#"* ]]; then
174+
export CONTROLLER_WEB_HOOK_URL="${CONTROLLER_WEB_HOOK_URL}#${CONTROLLER_API_KEY}"
190175
fi
191-
export ST_ACAPY_ADMIN_API_KEY_NAME="x-api-key"
192-
193-
# The redirect url can be a web link or the name of a template
194-
export CONTROLLER_CAMERA_REDIRECT_URL="wallet_howto"
195-
196-
# The number of time in seconds a proof request will be valid for
197-
export CONTROLLER_PRESENTATION_EXPIRE_TIME=10
198-
199-
# How long auth_sessions with matching the states in
200-
# CONTROLLER_SESSION_TIMEOUT_CONFIG_FILE are stored for in seconds
201-
export CONTROLLER_PRESENTATION_CLEANUP_TIME=86400
202-
203-
# Presentation record cleanup configuration
204-
# How long to retain presentation records in hours (default: 24 hours)
205-
export CONTROLLER_PRESENTATION_RECORD_RETENTION_HOURS=1
206-
207-
# Resource limits for cleanup operations to prevent excessive processing
208-
# Maximum presentation records to process per cleanup cycle (default: 1000)
209-
export CONTROLLER_CLEANUP_MAX_PRESENTATION_RECORDS=1000
210-
# Maximum connections to process per cleanup cycle (default: 2000)
211-
export CONTROLLER_CLEANUP_MAX_CONNECTIONS=2000
212-
213-
# The path to the auth_session timeouts config file
214-
export CONTROLLER_SESSION_TIMEOUT_CONFIG_FILE="/app/controller-config/sessiontimeout.json"
215-
216-
# Extend Variable Substitutions
217-
export CONTROLLER_VARIABLE_SUBSTITUTION_OVERRIDE="/app/controller-config/user_variable_substitution.py"
218-
219-
# template configuration
220-
export CONTROLLER_TEMPLATE_DIR="/app/controller-config/templates"
221-
222-
#controller app settings
223-
export INVITATION_LABEL=${INVITATION_LABEL:-"VC-AuthN"}
224-
export SET_NON_REVOKED="True"
225-
export ACAPY_PROOF_FORMAT=${ACAPY_PROOF_FORMAT:-indy}
226-
export USE_OOB_LOCAL_DID_SERVICE=${USE_OOB_LOCAL_DID_SERVICE:-"true"}
227-
export USE_CONNECTION_BASED_VERIFICATION=${USE_CONNECTION_BASED_VERIFICATION:-"true"}
228-
export WALLET_DEEP_LINK_PREFIX=${WALLET_DEEP_LINK_PREFIX:-"bcwallet://aries_proof-request"}
229-
230-
# Multi-pod configuration
231-
export CONTROLLER_REPLICAS=${CONTROLLER_REPLICAS:-3}
232-
233-
# Redis Configuration (required for multi-pod)
234-
export REDIS_HOST=${REDIS_HOST:-"redis"}
235-
export REDIS_PORT=${REDIS_PORT:-"6379"}
236-
export REDIS_PASSWORD=${REDIS_PASSWORD:-""}
237-
export REDIS_DB=${REDIS_DB:-"0"}
238-
export USE_REDIS_ADAPTER=${USE_REDIS_ADAPTER:-"true"}
239-
240-
# agent
241-
export AGENT_TENANT_MODE="${AGENT_TENANT_MODE:-single}"
242-
export AGENT_HOST=${AGENT_HOST:-aca-py}
243-
export AGENT_NAME="VC-AuthN Agent"
244-
export AGENT_HTTP_PORT=${AGENT_HTTP_PORT:-8030}
245-
export AGENT_ADMIN_PORT=${AGENT_ADMIN_PORT:-"8077"}
246-
export AGENT_ADMIN_URL=${AGENT_ADMIN_URL:-http://$AGENT_HOST:$AGENT_ADMIN_PORT}
247-
export AGENT_ENDPOINT=${AGENT_ENDPOINT:-http://$AGENT_HOST:$AGENT_HTTP_PORT}
248-
export AGENT_ADMIN_API_KEY=${AGENT_ADMIN_API_KEY}
176+
177+
# Agent Admin Mode: Append API Key if present
249178
export AGENT_ADMIN_MODE="admin-insecure-mode"
250179
if [ ! -z "${AGENT_ADMIN_API_KEY}" ]; then
251-
AGENT_ADMIN_MODE="admin-api-key ${AGENT_ADMIN_API_KEY}"
180+
export AGENT_ADMIN_MODE="admin-api-key ${AGENT_ADMIN_API_KEY}"
181+
fi
182+
183+
# Agent URLs: Construct from Host/Port if not explicitly set
184+
if [ -z "${AGENT_ENDPOINT}" ]; then
185+
export AGENT_ENDPOINT="http://${AGENT_HOST}:${AGENT_HTTP_PORT}"
186+
fi
187+
188+
if [ -z "${AGENT_ADMIN_URL}" ]; then
189+
export AGENT_ADMIN_URL="http://${AGENT_HOST}:${AGENT_ADMIN_PORT}"
252190
fi
253-
export AGENT_WALLET_SEED=${AGENT_WALLET_SEED}
254-
export MT_ACAPY_WALLET_ID=${MT_ACAPY_WALLET_ID}
255-
export MT_ACAPY_WALLET_KEY=${MT_ACAPY_WALLET_KEY}
256-
257-
# keycloak-db
258-
export KEYCLOAK_DB_NAME="keycloak"
259-
export KEYCLOAK_DB_USER="keycloak"
260-
export KEYCLOAK_DB_PASSWORD="keycloak"
261-
262-
# keycloak
263-
export KEYCLOAK_DB_VENDOR="postgres"
264-
export KEYCLOAK_DB_ADDR="keycloak-db"
265-
export KEYCLOAK_USER="admin"
266-
export KEYCLOAK_PASSWORD="admin"
267-
export KEYCLOAK_LOGLEVEL="WARN"
268-
export KEYCLOAK_ROOT_LOGLEVEL="WARN"
269-
270-
# wallet-db
271-
export WALLET_TYPE="postgres_storage"
272-
export WALLET_ENCRYPTION_KEY="key"
273-
export POSTGRESQL_WALLET_HOST="wallet-db"
274-
export POSTGRESQL_WALLET_PORT="5432"
275-
export POSTGRESQL_WALLET_DATABASE="wallet_db"
276-
export POSTGRESQL_WALLET_USER="walletuser"
277-
export POSTGRESQL_WALLET_PASSWORD="walletpassword"
278191
}
279192

280193
getStartupParams() {

0 commit comments

Comments
 (0)