skills/a6-persona-developer/SKILL.md
Persona skill for API developers building and testing APIs on APISIX using the a6 CLI. Provides decision frameworks for API design, route configuration, plugin selection, testing workflows, local development setup, and CI/CD integration patterns.
npx skillsauth add moonming/a6 a6-persona-developerInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are an API developer responsible for:
# Install a6
go install github.com/api7/a6/cmd/a6@latest
# Connect to your dev APISIX instance
a6 context create dev --server http://localhost:9180 --api-key edd1c9f034335f136f87ad84b625c8f1
# Verify connection
a6 health
# List all available plugins
a6 plugin list
# Get the schema for a specific plugin
a6 plugin get key-auth --output json
a6 plugin get limit-count --output json
a6 upstream create -f - <<'EOF'
{
"id": "my-api-backend",
"type": "roundrobin",
"nodes": {
"localhost:3000": 1
}
}
EOF
a6 route create -f - <<'EOF'
{
"id": "my-api",
"uri": "/api/*",
"methods": ["GET", "POST", "PUT", "DELETE"],
"upstream_id": "my-api-backend"
}
EOF
curl http://localhost:9080/api/hello
# Create a consumer with key-auth
a6 consumer create -f - <<'EOF'
{
"username": "dev-user",
"plugins": {
"key-auth": { "key": "my-dev-key" }
}
}
EOF
# Enable key-auth on the route
a6 route update my-api -f - <<'EOF'
{
"plugins": {
"key-auth": {}
}
}
EOF
# Test with the key
curl -H "apikey: my-dev-key" http://localhost:9080/api/hello
Use this decision tree to choose the right plugins for your API.
| Need | Plugin | Key Feature |
|------|--------|-------------|
| Simple API key | key-auth | Header/query param key lookup |
| JWT tokens | jwt-auth | RS256/HS256, token in header/query/cookie |
| Username/password | basic-auth | HTTP Basic authentication |
| HMAC signatures | hmac-auth | Request body signing, replay prevention |
| OAuth2/OIDC | openid-connect | Auth0, Okta, Keycloak integration |
| Need | Plugin | Key Feature |
|------|--------|-------------|
| Fixed window counter | limit-count | N requests per time window, Redis cluster support |
| Leaky bucket | limit-req | Smooth rate limiting, burst allowance |
| Need | Plugin | Key Feature |
|------|--------|-------------|
| Rewrite URI/headers | proxy-rewrite | Strip prefixes, add headers, change host |
| Modify response | response-rewrite | Change status code, body, headers |
| A/B testing, canary | traffic-split | Weighted routing, conditional matching |
| URL redirect | redirect | HTTP 301/302/307 redirects |
| Need | Plugin | Key Feature |
|------|--------|-------------|
| IP whitelist/blacklist | ip-restriction | CIDR support, allow/deny lists |
| CORS headers | cors | Cross-origin resource sharing |
| Access control | consumer-restriction | Restrict by consumer, group, or route |
| Need | Plugin | Key Feature |
|------|--------|-------------|
| Metrics | prometheus | Latency, status codes, bandwidth |
| Distributed tracing | zipkin or skywalking | Request trace correlation |
| Access logs | http-logger or kafka-logger | Structured log export |
a6 route create -f - <<'EOF'
{
"uri": "/api/*",
"upstream_id": "my-api-backend",
"plugins": {
"key-auth": {},
"limit-count": {
"count": 1000,
"time_window": 3600,
"key_type": "var",
"key": "consumer_name",
"rejected_code": 429
}
}
}
EOF
a6 route create -f - <<'EOF'
{
"uri": "/v1/*",
"upstream_id": "my-api-backend",
"plugins": {
"proxy-rewrite": {
"regex_uri": ["^/v1/(.*)", "/$1"]
}
}
}
EOF
a6 route update my-api -f - <<'EOF'
{
"plugins": {
"cors": {
"allow_origins": "http://localhost:3001",
"allow_methods": "GET,POST,PUT,DELETE,OPTIONS",
"allow_headers": "Authorization,Content-Type",
"allow_credential": true,
"max_age": 3600
}
}
}
EOF
When multiple routes share the same upstream and plugins, use a Service:
# Create service with shared config
a6 service create -f - <<'EOF'
{
"id": "my-api-service",
"upstream_id": "my-api-backend",
"plugins": {
"key-auth": {},
"cors": { "allow_origins": "*" }
}
}
EOF
# Routes inherit service config
a6 route create -f - <<'EOF'
{ "uri": "/users/*", "service_id": "my-api-service" }
EOF
a6 route create -f - <<'EOF'
{ "uri": "/orders/*", "service_id": "my-api-service" }
EOF
# If using the a6 repo's docker-compose
make docker-up
# Or manually
docker run -d --name etcd \
-p 2379:2379 \
-e ALLOW_NONE_AUTHENTICATION=yes \
bitnami/etcd:3.5
docker run -d --name apisix \
-p 9080:9080 -p 9180:9180 \
-v $(pwd)/apisix-config.yaml:/usr/local/apisix/conf/config.yaml \
apache/apisix:3.11.0-debian
# Create your dev config file
cat > dev-config.yaml <<'EOF'
upstreams:
- id: local-backend
type: roundrobin
nodes:
"host.docker.internal:3000": 1
consumers:
- username: dev
plugins:
key-auth:
key: dev-key
routes:
- id: api
uri: "/api/*"
upstream_id: local-backend
plugins:
key-auth: {}
EOF
# Apply it
a6 config sync -f dev-config.yaml
# See how APISIX routes a specific request
a6 debug trace --uri /api/users --method GET --header "apikey: dev-key"
# Watch APISIX error logs in real-time
a6 debug logs --follow
# Filter by log level
a6 debug logs --follow --level error
# See the merged config (route + service + plugins)
a6 route get my-api --output json | jq .
# .github/workflows/apisix.yml
- name: Validate APISIX config
run: a6 config validate -f apisix-config.yaml
- name: Deploy to staging
run: |
a6 context create staging --server ${{ secrets.STAGING_URL }} --api-key ${{ secrets.STAGING_KEY }}
a6 context use staging
a6 config diff -f apisix-config.yaml
a6 config sync -f apisix-config.yaml
# Export to Kubernetes-friendly format
a6 export --format kubernetes > k8s-apisix.yaml
# Export to standalone YAML
a6 export --format standalone > apisix-standalone.yaml
| Situation | Action |
|-----------|--------|
| New API endpoint | Create upstream → create route → add plugins → test |
| Add auth to existing API | Create consumer → update route with auth plugin → test |
| Multiple routes, same config | Create a Service → reference via service_id |
| Need rate limiting | Choose limit-count (fixed) or limit-req (smooth) → add to route |
| Backend URL changed | a6 upstream update <id> with new nodes |
| Debug 502 errors | a6 debug trace → a6 upstream health → check backend |
| Prepare for production | a6 config dump → commit to git → a6 config validate in CI |
| Test a new plugin | a6 plugin get <name> for schema → add to a test route → verify |
apisix-config.yaml in your repo, use
a6 config sync for deployments instead of imperative commandskey_type: "var" with key: "consumer_name"
for per-user limitsa6 plugin get <name> to see required/optional
fields before configuring--output json — pipe JSON output to jq for scripting and automation/* in productiontools
Core skill for working with the a6 CLI — the Apache APISIX command-line tool. Provides project conventions, command patterns, architecture overview, and development workflow. Load this skill when working on a6 source code, adding new commands, writing tests, or modifying any a6 component.
tools
Recipe skill for implementing multi-tenant API gateway patterns using the a6 CLI. Covers tenant isolation via Consumer Groups, host/path/header-based routing, per-tenant rate limiting, context forwarding with proxy-rewrite, and declarative config sync workflows for multi-tenant management.
tools
Recipe skill for configuring mutual TLS (mTLS) using the a6 CLI. Covers SSL certificate management, upstream mTLS to backend services, client certificate verification, and end-to-end mTLS setup from client through APISIX to upstream.
tools
Recipe skill for configuring upstream health checks using the a6 CLI. Covers active health checks (HTTP probing), passive health checks (response analysis), combining both, configuring healthy/unhealthy thresholds, and monitoring upstream node status.