Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,29 @@ This repo reads its config from etcd, but users never write etcd directly — th
- Exactly four divergence axes are registered as intentional and allowed: reference style (names here vs UUIDs in the CP), tenancy scoping (flat here vs org/environment there), credential custody (`key_hash` in documents here vs server-generated plaintext-once there), and CP-derived fields (`cost`, `telemetry_tags`). Anything else that diverges from cp-admin.yaml is drift — the planned cross-plane contract check will fail it.
- Why the CP spec and not this repo's schemas: the CP is spec-first behind a closed validator (its spec already is the authoritative field shape on that side), the spec renders into the customer-facing API reference, and this repo's schemas are generated from the implementation — a schema that follows the implementation cannot lead it. Naming drift has already cost real churn: #644 (the generated schema advertised `rps`/`rph` the validator rejected) and #657 (a wire-breaking rename because the field was named DP-first).

## AISIX Product Terminology

Use the following terms in public prose, generated API descriptions, release
notes, and configuration comments:

- **AISIX AI Gateway** is the open-source product. Use **open-source AISIX
gateway** when the distinction from AISIX Cloud matters; after establishing
the product, use **AISIX gateway** or **gateway**.
- **AISIX Cloud** is the commercial product umbrella. **Hybrid Cloud** is its
API7-hosted control-plane option, and **On-Premises** is its customer-hosted
control-plane option. Do not present **AISIX Hybrid Cloud** or **AISIX
On-Premises** as separate products.
- An AISIX gateway is a **data plane** only within AISIX Cloud architecture. Do
not call an independently operated open-source gateway a data plane.
- Do not use **standalone gateway** as a product label. `standalone mode` and
`managed mode` remain valid when describing runtime behavior.
- Avoid unqualified **self-hosted**. Name the component being operated, such as
the open-source AISIX gateway, the On-Premises control plane, or a self-hosted
upstream service.
- The Dashboard is the control plane's user interface, not the whole control
plane. Live AI requests pass through the gateway directly and do not pass
through the AISIX Cloud control plane or API7.

## Documentation Lives in api7/docs

**User-facing documentation is maintained in the `api7/docs` repository (published to <https://docs.api7.ai/ai-gateway/>), not in this repo.**
Expand Down
18 changes: 12 additions & 6 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,18 @@
# docker run --rm -v $(pwd)/config.example.yaml:/etc/aisix/config.yaml \
# aisix:dev
#
# Run, managed (aisix.cloud tenant — bake config + env-var overrides):
# Run, managed (connected to AISIX Cloud with env-var overrides):
# docker run --rm \
# -e AISIX_CONFIG_PATH=/etc/aisix/config.managed.yaml \
# -e AISIX_MANAGED__REGISTRATION_TOKEN=$DEPLOYMENT_TOKEN \
# -e AISIX_MANAGED__CP_BASE_URL=https://api.us.aisix.cloud \
# -e AISIX_MANAGED__CP_BASE_URL \
# -e AISIX_MANAGED__CP_ETCD_ENDPOINT \
# -e AISIX_MANAGED__CP_CERT_PEM \
# -e AISIX_MANAGED__CP_KEY_PEM \
# -e AISIX_MANAGED__CP_CA_PEM \
# -v aisix-mtls:/var/lib/aisix \
# aisix:dev
# The volume preserves the materialized mTLS bundle and gateway identity across
# container restarts.

# --- Stage 1: build ----------------------------------------------------------
FROM rust:1.93-bookworm AS builder
Expand Down Expand Up @@ -98,9 +103,10 @@ RUN --mount=type=bind,from=builder,source=/usr/local/bin/aisix,target=/mnt/aisix
&& apt-get purge -y --auto-remove libcap2-bin \
&& rm -rf /var/lib/apt/lists/*

# Bake the managed-mode bootstrap config so aisix.cloud tenants can
# `docker run` without mounting anything — env vars carry the per-DP
# secret bits (registration token + CP base URL).
# Bake the managed-mode bootstrap config so AISIX gateways managed by
# AISIX Cloud can `docker run` without mounting a configuration file.
# Environment variables provide the control-plane endpoints and gateway mTLS
# certificate bundle.
COPY config.managed.yaml /etc/aisix/config.managed.yaml

# Entrypoint script picks the config file via AISIX_CONFIG_PATH so the
Expand Down
37 changes: 21 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@

**One OpenAI-compatible API in front of every model.** Route, govern, secure, cache, and
observe all your LLM and AI-agent traffic from a single control point — shipped as one
static binary with low per-request overhead. Self-host for free, forever.
static binary with low per-request overhead. Run it in your infrastructure for free,
forever.

*Built by the original creators of [Apache APISIX](https://apisix.apache.org/).*

Expand Down Expand Up @@ -38,16 +39,19 @@ overhead.

It runs as a **single static binary** — low cold-start, lock-free config reads, and hot
configuration reloads with no restarts: declare resources in one `resources.yaml` and
reload on `SIGHUP`, or point the gateway at etcd for a multi-replica cluster. Run it **self-hosted and free**, or connect it to
reload on `SIGHUP`, or point the gateway at etcd for a multi-replica cluster. Run the
open-source gateway in your infrastructure, or connect it to
**[AISIX Cloud](https://api7.ai/ai-gateway?utm_source=github&utm_medium=readme&utm_campaign=cloud)**
for a managed control plane with team governance, budgets, audit, and a dashboard.

> **AISIX AI Gateway (this repo)** is the open-source core — the gateway, i.e. the data
> plane. **[AISIX Cloud](https://api7.ai/ai-gateway?utm_source=github&utm_medium=readme&utm_campaign=cloud)**
> adds a managed control plane on top, either operated by API7 (**Hybrid Cloud**) or run
> entirely in your own infrastructure (**On-Premises**). In every form the gateway runs in
> your environment and calls providers directly — live AI traffic never leaves your
> infrastructure. The proxy API is identical throughout.
for centralized management with team governance, budgets, audit, and a dashboard.

> **AISIX AI Gateway (this repo)** is the open-source product. It runs without a control
> plane using declarative configuration or etcd. When connected to
> **[AISIX Cloud](https://api7.ai/ai-gateway?utm_source=github&utm_medium=readme&utm_campaign=cloud)**,
> the same gateway serves as the data plane. AISIX Cloud adds a commercial control plane,
> either hosted by API7 (**Hybrid Cloud**) or hosted by you in your infrastructure
> (**On-Premises**). In both options, the gateway runs in your environment and calls
> providers directly; live AI traffic does not pass through the control plane or API7.
> The proxy API is identical throughout.
> **[Talk to us about AISIX Cloud →](https://api7.ai/contact?utm_source=github&utm_medium=readme&utm_campaign=cloud)**

## ⚡ Quickstart
Expand Down Expand Up @@ -131,8 +135,9 @@ For a multi-replica cluster, point the gateway at etcd instead — `resources_fi
one `base_url` and switch models without changing code.
- **A real gateway, in Rust.** Single static binary, low cold-start, lock-free config reads
on the hot path, native streaming.
- **Open-source core, free forever.** Apache-2.0, self-hostable end to end. Reach for
AISIX Cloud only when you want the managed control plane.
- **Open source, free forever.** Apache-2.0 licensed and built to run in your
infrastructure. Choose AISIX Cloud when you want centralized management through a
control plane and dashboard.
- **Production controls built in.** Routing & failover, rate limits, guardrails, caching,
and observability ship in the box. (Budgets and spend caps are an AISIX Cloud feature —
the gateway enforces the control plane's decisions.)
Expand Down Expand Up @@ -206,7 +211,7 @@ OpenAI-shaped.

| Adapter family | Reaches | Wire shape · auth |
|---|---|---|
| `openai` | OpenAI **+ any OpenAI-compatible vendor** — DeepSeek, Groq, Mistral, Together, Fireworks, Perplexity, vLLM, Ollama, self-hosted | OpenAI chat completions · Bearer |
| `openai` | OpenAI **+ any OpenAI-compatible vendor** — DeepSeek, Groq, Mistral, Together, Fireworks, Perplexity, vLLM, Ollama, or self-hosted OpenAI-compatible endpoints | OpenAI chat completions · Bearer |
| `anthropic` | Anthropic Claude | Anthropic Messages · `x-api-key` |
| `bedrock` | AWS Bedrock — Anthropic, Meta Llama, Mistral, Cohere, Amazon Titan/Nova, AI21 | Bedrock Converse + `/invoke` · SigV4 |
| `vertex` | Google Vertex AI (Gemini) | Vertex `:generateContent` · OAuth2 |
Expand All @@ -219,8 +224,8 @@ Plus specialized handling for vendor quirks (e.g. DeepSeek reasoning content) an
## ☁️ Open source vs AISIX Cloud

Same gateway binary, same proxy API — in every form the gateway runs in your environment.
**AISIX Cloud** adds a managed control plane on top, either operated by API7
(**Hybrid Cloud**) or running entirely in your infrastructure (**On-Premises**).
**AISIX Cloud** adds a commercial control plane, either hosted by API7
(**Hybrid Cloud**) or hosted in your infrastructure (**On-Premises**).

<table>
<tr>
Expand Down Expand Up @@ -266,7 +271,7 @@ Same gateway binary, same proxy API — in every form the gateway runs in your e
| Usage & cost | Export logs, metrics, and usage events yourself | Managed usage views, model pricing catalog, spend reporting |
| Surface | Status endpoints, OpenAPI read surface, playground | Full dashboard + per-environment playground |

→ **Want the managed control plane, governance, budgets, and dashboard?**
→ **Want the AISIX Cloud control plane, governance, budgets, and dashboard?**
**[Talk to API7](https://api7.ai/contact?utm_source=github&utm_medium=readme&utm_campaign=cloud)** about
Hybrid Cloud or On-Premises, or **[book a demo](https://api7.ai/contact?utm_source=github&utm_medium=readme&utm_campaign=demo)**.

Expand Down
12 changes: 7 additions & 5 deletions RELEASING.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# Releasing

How an AISIX data-plane release is cut. Order matters: downstream packaging
(AISIX Cloud and the self-hosted bundle) pins the exact data-plane image
version, so the data plane is always tagged and published **first**.
How an AISIX AI Gateway release is cut. Order matters: downstream packaging
(AISIX Cloud and the On-Premises package, whose artifact name is
`aisix-self-hosted`) pins the exact gateway image version, so the gateway is
always tagged and published **first**.

## 1. Tag

Expand All @@ -22,7 +23,7 @@ Pushing the tag triggers two workflows:
- **`release-draft.yml`** creates a **draft** GitHub Release for the tag. The
draft already leads with a version-stamped **Get started + Download** header
(from [`.github/release-notes-header.md`](.github/release-notes-header.md):
docs, self-hosted quickstart, and the `docker pull` command), then a commented
docs, gateway quickstart, and the `docker pull` command), then a commented
curated-notes scaffold to fill in, then GitHub's auto-generated **What's
Changed** list as a starting skeleton.

Expand Down Expand Up @@ -59,5 +60,6 @@ version for patch releases.
## 4. Downstream

Only after the images are published, downstream release flows (AISIX Cloud /
the self-hosted package) may tag the same `vX.Y.Z` — their packaging pulls
the On-Premises package named `aisix-self-hosted`) may tag the same `vX.Y.Z` —
their packaging pulls
`docker.io/api7/aisix:X.Y.Z` and fails if it does not exist yet.
4 changes: 2 additions & 2 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ For what the gateway does today — including [semantic routing](https://docs.ap
- **Next** — planned after the current focus.
- **Later** — on the longer-term horizon.

The **Surface** column shows where a capability lands: **Gateway** is the AISIX AI Gateway data plane; **Cloud** is the AISIX Cloud control plane and dashboard.
The **Surface** column shows where a capability lands: **Gateway** is the AISIX AI Gateway runtime; **Cloud** is the AISIX Cloud control plane and dashboard.

## Now

Expand All @@ -30,7 +30,7 @@ The **Surface** column shows where a capability lands: **Gateway** is the AISIX
| Conditional and wildcard routing | Route on request metadata, headers, and tags, and match upstreams by wildcard names such as `provider/*`. | Gateway |
| Prompt management | Store, version, and reuse prompt templates with variables, resolved at the gateway. | Gateway · Cloud |
| Caller key rotation experience | Self-service key rotation in the dashboard, plus scheduled auto-rotation with a grace overlap. | Cloud |
| Production-path playground | Run the Cloud playground through the managed data plane so it reflects real routing, caching, guardrails, and rate limiting. | Cloud |
| Production-path playground | Run the Cloud playground through a connected AISIX gateway so it reflects real routing, caching, guardrails, and rate limiting. | Cloud |
| Cross-provider endpoint parity | Consistent embeddings, image generation, and Responses behavior across more providers. | Gateway |

## Later
Expand Down
8 changes: 4 additions & 4 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ etcd:
dial_timeout_ms: 5000
request_timeout_ms: 5000
# Optional TLS / mTLS bundle. Required when connecting to an
# aisix.cloud DP Manager (endpoint is https:// and the CP issues
# AISIX Cloud Data Plane Manager (endpoint is https:// and the control plane issues
# a client cert via IssueAIDataplaneCertificate). Uncomment and
# point to your mTLS bundle.
# tls:
Expand Down Expand Up @@ -134,10 +134,10 @@ observability:
endpoint: "http://127.0.0.1:4317"
sample_ratio: 1.0

# Managed-mode switch. Uncomment when running as an aisix.cloud
# tenant: the admin API and Playground will NOT be bound — all
# Managed-mode switch. Uncomment when connecting the gateway to
# AISIX Cloud: the admin API and Playground will NOT be bound — all
# configuration flows from etcd via the mTLS channel above, driven
# by the aisix.cloud control plane.
# by the AISIX Cloud control plane.
# managed:
# enabled: true

Expand Down
7 changes: 4 additions & 3 deletions config.managed.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# aisix — managed-mode bootstrap config (aisix.cloud tenant).
# AISIX gateway — managed-mode bootstrap configuration for AISIX Cloud.
#
# Used by the official Docker image as `/etc/aisix/config.yaml`.
# Baked into the official Docker image as `/etc/aisix/config.managed.yaml`.
# Select it by setting `AISIX_CONFIG_PATH` to that path.
# Only the bare minimum is set here:
#
# - `managed.enabled: true` always on for this image
# - `managed.enabled: true` always on in this bootstrap configuration
# - `etcd.endpoints: [placeholder]` overridden at boot from managed
# CP endpoint config
# - `admin.admin_keys: [placeholder]` validation requires the slot,
Expand Down
20 changes: 10 additions & 10 deletions crates/aisix-admin/src/openapi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const OPENAPI_JSON_BASE: &str = r##"{
"info": {
"title": "AISIX Admin API",
"version": "dev",
"description": "The AISIX Admin API is the self-hosted management interface for configuring the gateway at runtime. Use it when you operate AISIX directly and need to create or update models, caller API keys, provider credentials, guardrails, cache policies, and observability exporters.\n\nThe write endpoints (POST, PUT, DELETE) are deprecated in favor of declarative configuration: load resources from a `resources_file` (`resources.yaml`) or write them to etcd directly. Write endpoints remain functional, and every mutating response carries a `Deprecation` header (RFC 9745) plus a `Link` header with `rel=\"deprecation\"` pointing at the migration documentation. Read endpoints are not deprecated.\n\nManaged deployments do not expose this listener. Configure managed gateways through the AISIX managed control plane."
"description": "The AISIX Admin API configures an open-source AISIX gateway at runtime. Use it when you operate the gateway directly and need to create or update models, caller API keys, provider credentials, guardrails, cache policies, and observability exporters.\n\nThe write endpoints (POST, PUT, DELETE) are deprecated in favor of declarative configuration: load resources from a `resources_file` (`resources.yaml`) or write them to etcd directly. Write endpoints remain functional, and every mutating response carries a `Deprecation` header (RFC 9745) plus a `Link` header with `rel=\"deprecation\"` pointing at the migration documentation. Read endpoints are not deprecated.\n\nGateways connected to AISIX Cloud do not expose this listener. Configure them through AISIX Cloud."
},
"paths": {
"/livez": {
Expand Down Expand Up @@ -3947,7 +3947,7 @@ const OPENAPI_JSON_BASE: &str = r##"{
}
},
"additionalProperties": false,
"description": "Self-hosted Admin API request body for creating or updating a caller API key. Ownership fields supplied by the managed control plane are not accepted by this API."
"description": "AISIX Admin API request body for creating or updating a caller API key on an open-source AISIX gateway. Ownership fields supplied by AISIX Cloud are not accepted by this API."
}
}
},
Expand Down Expand Up @@ -4853,7 +4853,7 @@ mod tests {
}

#[tokio::test]
async fn openapi_uses_self_hosted_apikey_request_schema() {
async fn openapi_uses_open_source_gateway_apikey_request_schema() {
let parsed: serde_json::Value =
serde_json::from_str(merged_openapi()).expect("merged_openapi must parse");
for (path, method) in [
Expand All @@ -4866,7 +4866,7 @@ mod tests {
parsed["paths"][path][method]["requestBody"]["content"]["application/json"]
["schema"]["$ref"],
"#/components/schemas/ApiKeyRequest",
"{method} {path} should document the self-hosted Admin API request body"
"{method} {path} should document the open-source gateway Admin API request body"
);
}

Expand All @@ -4875,33 +4875,33 @@ mod tests {
assert_eq!(request["required"][1], "allowed_models");
assert!(
request["properties"].get("allowed_tools").is_some(),
"self-hosted API key requests must document MCP tool access"
"open-source gateway API key requests must document MCP tool access"
);
let request_allowed_tools = request["properties"]["allowed_tools"]["description"]
.as_str()
.unwrap();
assert!(
request_allowed_tools.contains("omitted, set to `null`, or set to an empty list"),
"self-hosted API key request schema must document no-access tool-list behavior"
"open-source gateway API key request schema must document no-access tool-list behavior"
);
assert!(
request_allowed_tools.contains("<server>__*"),
"self-hosted API key request schema must document the per-server wildcard"
"open-source gateway API key request schema must document the per-server wildcard"
);
assert!(
request["properties"].get("allowed_agents").is_some(),
"self-hosted API key requests must document A2A agent access"
"open-source gateway API key requests must document A2A agent access"
);
let request_allowed_agents = request["properties"]["allowed_agents"]["description"]
.as_str()
.unwrap();
assert!(
request_allowed_agents.contains("omitted, set to `null`, or set to an empty list"),
"self-hosted API key request schema must document no-access agent-list behavior"
"open-source gateway API key request schema must document no-access agent-list behavior"
);
assert!(
request_allowed_agents.contains("grants every agent"),
"self-hosted API key request schema must document wildcard agent access"
"open-source gateway API key request schema must document wildcard agent access"
);
let public = &parsed["components"]["schemas"]["PublicApiKey"];
assert!(
Expand Down
Loading
Loading