a7-recipe-multi-tenant
Overview
Multi-tenancy in API7 EE is built from three layers:
- Gateway groups for runtime isolation.
- Consumers and credentials for tenant identity.
- Service-backed routes for tenant APIs.
For route traffic, use the current a7 model:
- Create a service with upstream nodes.
- Create routes with
pathsandservice_id. - Create consumers and credentials separately.
When to Use
- Separate
dev,staging, andprodgateway configurations. - Serve SaaS tenants with different limits or auth policies.
- Isolate regulated or high-priority tenants by gateway group.
- Let platform teams own shared routing while app teams own service targets.
Approach A: Gateway Groups for Isolation
Gateway groups are the primary isolation boundary.
a7 gateway-group create premium-tier --desc "High-performance tier for paid customers"
a7 gateway-group create standard-tier --desc "Standard tier for free and trial users"
a7 gateway-group create platform --desc "Shared platform gateway group for tenant consumers and routes"
Each group can have its own global policies:
a7 global-rule create -g standard-tier -f - <<'EOF'
{
"plugins": {
"limit-count": {
"count": 5000,
"time_window": 3600,
"rejected_code": 429
}
}
}
EOF
Approach B: Consumers and Credentials
Current API7 EE does not expose consumer group management through the Admin API.
Model tenants as consumers, attach per-consumer plugins when needed, and create
credentials with a7 credential create.
a7 consumer create -g platform -f - <<'EOF'
{
"username": "startup-xyz",
"desc": "Free tier tenants",
"plugins": {
"limit-count": {
"count": 100,
"time_window": 86400,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429,
"rejected_msg": "Free tier quota exceeded"
}
}
}
EOF
a7 credential create -g platform --consumer startup-xyz --plugins-json '{"key-auth":{"key":"startup-xyz-key"}}'
a7 consumer create -g platform -f - <<'EOF'
{
"username": "acme-corp",
"desc": "Pro tier tenants",
"plugins": {
"limit-count": {
"count": 10000,
"time_window": 86400,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429,
"rejected_msg": "Pro tier quota exceeded"
}
}
}
EOF
a7 credential create -g platform --consumer acme-corp --plugins-json '{"key-auth":{"key":"acme-secret-key"}}'
Approach C: Tenant-Aware Service Route
Create the backend service first:
a7 service create -g platform -f - <<'EOF'
{
"id": "tenant-api-service",
"name": "tenant-api-service",
"upstream": {
"type": "roundrobin",
"nodes": [
{"host": "internal-service", "port": 8080, "weight": 1}
]
}
}
EOF
Create the tenant route with paths and service_id:
a7 route create -g platform -f - <<'EOF'
{
"id": "multi-tenant-api",
"name": "multi-tenant-api",
"paths": ["/service/*"],
"service_id": "tenant-api-service",
"plugins": {
"key-auth": {},
"proxy-rewrite": {
"headers": {
"set": {
"X-Tenant-ID": "$consumer_name",
"X-User-ID": "$consumer_name",
"X-Gateway-Group": "platform"
}
}
}
}
}
EOF
Declarative Per-Group Management
Use one declarative file per gateway group and apply it with -g. This matches
the current a7 config sync workflow.
version: "1"
services:
- id: tenant-api-service
name: tenant-api-service
upstream:
type: roundrobin
nodes:
- host: internal-service
port: 8080
weight: 1
routes:
- id: multi-tenant-api
name: multi-tenant-api
paths:
- /service/*
service_id: tenant-api-service
plugins:
key-auth: {}
proxy-rewrite:
headers:
set:
X-Tenant-ID: "$consumer_name"
X-User-ID: "$consumer_name"
X-Gateway-Group: platform
Apply it:
a7 config sync -g platform -f platform-tenants.yaml
Use a7 consumer create -f and a7 credential create for tenant identities and
key material.
Verification
a7 consumer list -g platform
a7 credential list -g platform --consumer startup-xyz
a7 service get tenant-api-service -g platform -o json
a7 route get multi-tenant-api -g platform -o json
Traffic verification requires a deployed gateway:
curl -i -H "apikey: startup-xyz-key" https://gateway.example.com/service/resource
curl -i -H "apikey: acme-secret-key" https://gateway.example.com/service/resource
The backend should receive X-Tenant-ID, X-User-ID, and X-Gateway-Group
headers after successful authentication.
Important Considerations
- Use different gateway groups for strict runtime isolation.
- Use consumer-level plugins for tenant-specific policies inside one gateway group.
- Keep credentials under
a7 credential, not embedded directly in consumers. a7 config sync -gmanages one gateway group at a time.- Use raw consumer payloads for fields that do not have first-class CLI flags.
This page is generated from a7-recipe-multi-tenant/SKILL.md in the api7/a7 repository. Browse all skills on the AI Agent Skills page.