Slackbot
05/20/2026, 7:30 PMAsk Inkeep
05/20/2026, 7:30 PMAsk Inkeep
05/20/2026, 7:31 PMDataSourceEntry configurations dynamically (2) . This solves your persistence problem by centralizing the tenant-to-data-source mapping outside OPAL itself.
*How it works:*
1. Configure OPAL_DATA_CONFIG_SOURCES to point to your external API endpoint (set once, no restarts needed)
2. Your external API returns multiple data source entries programmatically based on registered tenants
3. When clients restart, they fetch the current tenant list from your external API
This approach handles pagination logic and can serve different configurations based on client identity using JWT claims .
Single-Topic Architecture Recap
With single-topic configuration, all tenants share one topic (1) :
All tenants: OPAL_DATA_TOPICS=tenant_data # no restart needed when adding tenants
Each tenant gets its own data source publishing to the same topic with different destination paths :
• *Tenant 1*: External data source A → tenant_data topic → /acl/tenant1 path
• *Tenant 2*: External data source B → tenant_data topic → /acl/tenant2 path
Adding Tenants Dynamically
When you add a tenant via /data/config, the update triggers immediately :
curl -X POST <http://localhost:7002/data/config> \
-H "Content-Type: application/json" \
-d '{
"entries": [{
"url": "<http://example_external_data_provider:80/acl/tenant1>",
"topics": ["tenant_data"],
"dst_path": "/acl/tenant1"
}],
"reason": "Add tenant1 data source"
}'
No service restart is required when adding new tenants (1) (3) .
Addressing Your Questions
*1. Dynamic tenant onboarding pattern:*
Yes, build an external config API that returns your tenant-to-data-source mappings (2) . You can break down data loading into multiple entries where each entry fetches a different subset and stores it at different paths .
*2. Persistence of /data/config entries:*
The documentation confirms that using an external API server for dynamic configuration is the supported pattern for handling persistence . The external server maintains state, not OPAL itself.
*3. Client-side filtering for service mesh:*
The single-topic approach means all OPAL clients subscribed to tenant_data receive all notifications and must hold all tenants' data (1) . This is a known trade-off:
*Benefits:*
• No service restarts required when adding tenants
• Better resource utilization - tenants accessible from all OPAL Clients
• Real-time data source notifications propagate to all clients without restarts
*Challenges:*
• Higher memory footprint per client - every OPAL Client must hold all tenants' data
• Increased Data Source load - all OPAL Clients fetch all tenants' data
If you need per-tenant resource isolation where each client only stores its tenant's data, the multi-topic architecture would be more appropriate .
Would you like guidance on implementing the external config API server pattern?Ask Inkeep
05/20/2026, 7:31 PMVitaly Orbidan
05/20/2026, 7:34 PMdst_path)
• Two deployment modes: service mesh (1 OPA per tenant) and gateway (1 OPA for all tenants)
How I'm using it:
I push tenant data via POST /data/config using two patterns:
Pattern A: External URL
{
"entries": [
{
"url": "<http://data-api/tenant1/roles>",
"dst_path": "/acl/tenant1",
"topics": [
"tenant_data"
]
}
]
}
Pattern B: Inline Data
{
"entries": [
{
"url": "<inline://tenant1-roles>",
"dst_path": "/acl/tenant1",
"topics": [
"tenant_data"
],
"data": {
"admin": [
"read",
"write"
]
}
}
]
}
The problem:
Neither pattern persists anything. When a client restarts:
• External URL — the dst_path → url mapping is lost
• Inline Data — the actual data is lost
Clients only know about OPAL_DATA_CONFIG_SOURCES (static, requires restart).
Questions:
1. What's the recommended pattern for dynamic tenant onboarding with single-topic? Should I build an external config API?
2. Would persistence of /data/config entries be useful upstream? Currently persistence is gated behind OPAL_SCOPES=1.
3. Bonus: For service mesh, is there a way to filter updates client-side so each OPA only stores its tenant's data? (e.g., OPAL_DATA_FILTER_PATH=/acl/tenant1)
Trying to avoid building a separate data config registry or using scopes when I don't need per-tenant policies. Any thoughts? 🙏Ask Inkeep
05/20/2026, 7:35 PMVitaly Orbidan
05/20/2026, 7:37 PM"data": {...} in the entry)? If I push data directly via POST /data/config (not fetched from a URL), and the client restarts, that data is lost. Is there a recommended pattern for this, or should inline data always be avoided in favor of external URLs?
For the service mesh case, would there be interest in a client-side filter feature? Something like OPAL_DATA_FILTER_PATH=/acl/tenant1 that discards entries not matching the path. This would allow single-topic simplicity while avoiding memory bloat on sidecars.Vitaly Orbidan
05/20/2026, 7:39 PMAsk Inkeep
05/20/2026, 7:39 PMAsk Inkeep
05/20/2026, 7:39 PMdata field (1) . However, the sources don't explicitly address persistence of inline data after client restarts. The recommended pattern consistently points to external URLs rather than inline data for dynamic updates (1) (2) .
When using external data sources, the endpoint should return a DataSourceConfig with entries that point to URLs where data can be fetched (1) . This ensures clients can refetch data after restarts.
*Client-Side Filtering*
The sources don't document a built-in OPAL_DATA_FILTER_PATH or similar client-side filtering mechanism. The single-topic architecture explicitly states that "all OPAL clients subscribed to tenant_data receive all notifications and must hold all tenants' data" (3) .
The documented trade-off is clear :
• *Single-topic*: All clients hold all tenant data (higher memory per client)
• *Multi-topic*: Each client holds only its tenant's data (per-tenant resource isolation)
If you need per-tenant resource isolation where each client only stores its tenant's data, the multi-topic architecture would be the appropriate choice .
*Recommendation*
For inline data that needs to persist across client restarts, the external API server pattern is the documented approach (1) (2) . Your external API would:
1. Store the tenant data persistently
2. Return DataSourceEntry configurations with URLs pointing to endpoints that serve the data
3. Handle the data fetch when clients restart
For the client-side filtering feature request, that appears to be functionality not currently documented in OPAL. You might consider opening a feature request on the OPAL GitHub repository.Ask Inkeep
05/20/2026, 7:39 PMAsk Inkeep
05/20/2026, 7:39 PMAsk Inkeep
05/20/2026, 7:39 PMinline_data field (1) . When configured as an external data source, entries can include inline data, but the sources don't explicitly address how inline data persists after client restarts.
The external API pattern returns DataSourceConfig with entries pointing to URLs :
DataSourceConfig(
entries=[
DataSourceEntry(
url=f"{BACKEND_PUBLIC_URL}/v1/policy/config",
topics=topics,
config=HttpFetcherConfig(
headers={'Authorization': f"Bearer {pdp.client_secret}"}
)
)
],
)
The recommended approach consistently emphasizes external URLs rather than inline data for dynamic updates (1) (2) . The external API server can break down data loading into multiple entries where each entry fetches a different subset and stores it at different paths (2) .
*Client-Side Filtering*
The sources don't document a built-in client-side filtering mechanism like OPAL_DATA_FILTER_PATH. The single-topic architecture explicitly states that all OPAL clients subscribed to tenant_data receive notifications, with the documented challenge being "Higher memory footprint per client - every OPAL Client must hold all tenants' data" (3) .
The architecture trade-offs are :
• *Single-topic*: Better resource utilization, no restarts needed, but all clients hold all tenant data
• *Multi-topic*: Per-tenant resource isolation, but requires dedicated OPAL Client instances per tenant
For feature requests around inline data persistence or client-side filtering, I'd recommend reaching out to the team via the Permit Slack Community to discuss whether these capabilities align with the product roadmap.Ask Inkeep
05/20/2026, 7:39 PMNatalia Edelson
05/20/2026, 7:55 PMVitaly Orbidan
05/20/2026, 8:01 PMAsk Inkeep
05/20/2026, 8:01 PMdavid
05/21/2026, 6:56 AM