On-Premises Configuration
Configure the On-Premises deployment through a Docker Compose .env file or Helm values, depending on how you install the control plane.
Use this reference with On-Premises Installation when you need to review or customize the generated deployment configuration.
Preserve these settings with the matching database backup. See Backup and Recovery for the complete recovery set and restore order.
These settings configure the on-premises control plane package. They are separate from AISIX gateway runtime environment variables. For gateway runtime variables, see Environment Variables.
Deployment Mode
cp-api runs in one of two deployment modes. The mode is deployment.mode in the cp-api configuration file, AISIX_CLOUD_DEPLOYMENT_MODE in the environment, and api.deploymentMode in the Helm chart. The default is on-premises, and it is the only mode supported for a self-hosted deployment. The other value, saas, is the mode the API7-hosted service runs in, and is not supported on a deployment you host. cp-api refuses to start with any other value.
In on-premises mode, cp-api enforces the following, and the dashboard hides what does not apply:
- Nobody can sign up on their own. An account is created from an invitation: the invitee registers through the link in it. See Invite a Member. A sign-up request without a valid invitation is refused with
403 SIGN_UP_DISABLEDor403 INVITATION_INVALID. - Nobody can create an organization. The first organization is created together with the first administrator. A request to create another one is refused with
403 ORG_CREATION_DISABLED. A control plane upgraded from 1.5.x or earlier that still holds several organizations refuses console requests with403 ORG_CONSOLIDATION_REQUIREDuntil an owner keeps one of them and deletes the rest. See Consolidate Several Organizations into One. - There are no billing pages or plans.
- Sign-up asks the invitee to accept no hosted-service terms.
cp-api's own outbound calls may reach private addresses unless you disallow them. See Private Network Access.
The Docker Compose package does not pass the variable to cp-api, so a package installation always runs in on-premises mode.
The saas mode has requirements and settings of its own, which do not apply to an on-premises control plane:
- It requires an SMTP relay, because every new account must verify its email address.
cp-apirefuses to start insaasmode whensmtp.host(AISIX_CLOUD_SMTP_HOST) is empty, and the Helm chart refuses to render whenapi.smtp.hostis empty. domain_verification.dns_server(AISIX_CLOUD_DOMAIN_VERIFICATION_DNS_SERVER,api.domainVerification.dnsServerin the Helm chart) is the DNS server, ashost:port, that organization domain verification sends its TXT lookups to. It is optional, and empty, the default, uses the system resolver. Anon-premisescontrol plane has no organization domains and ignores it, butcp-apistill refuses to start when the value is set and is not ahost:portpair.
Docker Compose Environment Variables
The Docker Compose package reads environment variables from ./aisix-self-hosted/.env. The quickstart and offline package generate this file on first start. Back it up with the database: it contains the database password and master key, and it is not included in later package archives.
During a normal in-place upgrade, run.sh updates AISIX_VERSION to match the extracted package. It preserves the other settings and secrets in .env.
Run the Docker Compose commands on this page from the ./aisix-self-hosted directory.
Images and Release Version
| Variable | Purpose |
|---|---|
AISIX_VERSION | Package-owned release tag used by the images unless you set an individual image override. run.sh updates it during an upgrade. |
AISIX_API_IMAGE | Optional image override for cp-api. The cp-api image also carries the dashboard. |
AISIX_DPM_IMAGE | Optional image override for dp-manager. |
AISIX_CLOUD_DP_IMAGE | Optional AISIX gateway image override used in generated gateway install snippets. Without it, the package hands out docker.io/api7/aisix:${AISIX_VERSION}, the gateway of the same release. |
Individual image overrides remain in effect across package upgrades.
Database
| Variable | Purpose |
|---|---|
POSTGRES_USER | PostgreSQL user for the bundled database. |
POSTGRES_PASSWORD | PostgreSQL password for the bundled database. Use a strong URL-safe value because it is embedded in a postgres:// URL. |
POSTGRES_DB | PostgreSQL database name. |
These variables configure only the bundled PostgreSQL service. The package does not expose external database URL overrides in .env. Use the Helm installation when the control plane must connect to an external PostgreSQL database.
Secrets
| Variable | Purpose |
|---|---|
AISIX_CLOUD_MASTER_KEY | Base64-encoded 32-byte AES key used for envelope encryption. The same value is also used by dp-manager. |
AISIX_CLOUD_MASTER_KEY_ID | Identifier stored with encrypted rows so the control plane can identify the wrapping key. |
AISIX_CLOUD_SMTP_PASSWORD | Optional SMTP relay password. See Email. |
Do not change AISIX_CLOUD_MASTER_KEY on an existing deployment unless you are following a master-key rotation procedure. Changing it without preserving the previous key can make encrypted data unreadable.
First Administrator
| Variable | Purpose |
|---|---|
AISIX_CLOUD_BOOTSTRAP_ADMIN_EMAIL | Email address of the first administrator. run.sh writes admin@example.com when it generates .env. |
AISIX_CLOUD_BOOTSTRAP_ADMIN_PASSWORD | Initial password of the first administrator, 12 to 128 characters. run.sh writes a random one when it generates .env. |
run.sh writes both when it generates .env on the first start and prints them once after the stack is up. It never changes an existing .env. On a start where the database has no users yet, cp-api creates the organization Default with this account as its owner, and the account must change its password at the first sign-in. This happens at most once in the life of a database: changing either value afterwards changes nothing. Set both or neither: cp-api refuses to start with only one. With both empty, cp-api starts, logs a warning, and nobody can sign in. See Sign In as the First Administrator.
Recover a Missing CA Root
Use this recovery override only when cp-api or dp-manager refuses to start with ca_root row missing but dp_certificates has rows, and only after confirming that the control plane is connected to the intended database. Minting a new root CA invalidates every existing gateway mTLS chain. It does not recover the missing root.
If you cannot restore the missing root from a complete database backup and intend to replace it, add the following setting to .env:
AISIX_CLOUD_ALLOW_FRESH_BOOTSTRAP=1
Recreate both services so either process can bootstrap the replacement CA:
docker compose up -d --wait api dpm
After both services are healthy, remove AISIX_CLOUD_ALLOW_FRESH_BOOTSTRAP from .env and run the same command again to recreate them without the override. When both services are healthy again, re-enroll every AISIX gateway; certificates issued under the missing root no longer authenticate.
Runtime URLs
| Variable | Purpose |
|---|---|
AISIX_CLOUD_PUBLIC_BASE_URL | Browser-facing control-plane origin, such as https://aisix.example.com. Sign-in always trusts this origin, and invitation and password reset links point to it. Single sign-on builds its service provider URLs from it, so it must be the URL browsers actually use. |
AISIX_CLOUD_DPMGR_BASE_URL | dp-manager mTLS endpoint that AISIX gateway hosts can reach. An https:// URL such as https://dpm.example.com:7944, whose host may be a DNS name or an IP address. |
AISIX_TRUSTED_ORIGINS | Additional browser origins allowed to sign in, provided as a comma-separated list of bare origins or https://*<suffix> patterns. The public base URL and its loopback twin are trusted automatically. cp-api logs and ignores an entry it cannot read as an origin. |
AISIX_TRUSTED_PROXIES | Reverse proxies in front of cp-api, as comma-separated CIDRs, whose X-Forwarded-For header cp-api believes when it rate-limits sign-in and password reset per client. Empty by default. See Rate Limits Behind a Reverse Proxy. |
AISIX_CLOUD_CORS_ALLOWED_ORIGINS | Browser origins allowed to call cp-api routes under /api/* cross-origin, including /api/auth/*, provided as a comma-separated list. Empty by default, which writes no CORS headers at all. For cross-origin sign-in, add the origin to AISIX_TRUSTED_ORIGINS as well. See Cross-Origin Browser Access for the accepted entries. |
Set AISIX_CLOUD_PUBLIC_BASE_URL and AISIX_CLOUD_DPMGR_BASE_URL before exposing the deployment outside the local host or container network.
Compose passes AISIX_CLOUD_DPMGR_BASE_URL to the dpm service as well, because dp-manager issues its TLS server certificate for that host. Recreate both api and dpm after changing it.
Pricing Catalog
The packaged Docker Compose file runs cp-api in offline pricing mode by default. It sets AISIX_CLOUD_PRICESYNC_SNAPSHOT_PATH on the api service to a snapshot baked into the cp-api image, so the control plane can initialize model pricing without contacting models.dev.
In online mode, when a synchronization fails while the catalog is still empty, such as on a host that cannot reach models.dev, cp-api loads that same baked snapshot instead. It never replaces an existing catalog with the snapshot, and it keeps trying the online synchronization every 24 hours.
The package exposes the pricing mode through .env:
| Variable | Purpose |
|---|---|
AISIX_CLOUD_PRICESYNC_SNAPSHOT_PATH | Select offline mode when it contains a snapshot path. When the variable is absent, Compose uses the in-image snapshot. An explicitly empty value selects online mode. |
AISIX_CLOUD_PRICESYNC_URL | Override the models.dev catalog URL in online mode, for example with an internal mirror. When it is empty, online mode uses https://models.dev/api.json. |
To use online pricing, add an empty snapshot-path assignment to .env. Add the URL only when you need to use a different catalog endpoint:
AISIX_CLOUD_PRICESYNC_SNAPSHOT_PATH=
Recreate cp-api after changing either setting:
docker compose up -d api
Keep these overrides in .env, not docker-compose.yaml, because extracting a later package replaces the Compose file.
Private Network Access
By default, an on-premises control plane lets these outbound connections reach private, internal, and loopback addresses, so models, webhook receivers, and documents on your internal network work without configuration. Each variable overrides that default for one kind of connection. Set it to false to refuse private destinations, as a server-side request forgery (SSRF) protection, when the operators of the control plane should not be able to reach your internal network through it.
| Variable | Purpose |
|---|---|
AISIX_PLAYGROUND_ALLOW_PRIVATE_IPS | Whether the dashboard playground may reach the provider key's api_base on a private address. See Playground. |
AISIX_CLOUD_NOTIFY_ALLOW_PRIVATE_URLS | Whether budget notifications may reach a private webhook receiver or Slack proxy. |
AISIX_CLOUD_MCP_SPEC_ALLOW_PRIVATE_URLS | Whether the control plane may fetch an MCP server's OpenAPI document from a private spec_url. When it may not, provide spec_content instead. |
AISIX_GUARDRAIL_TEST_CONNECTION_ALLOW_INSECURE | Whether the guardrail connection test may reach plain HTTP endpoints, private addresses, and hosts other than Azure, such as an internal or Private Link endpoint. |
Each variable accepts true, false, 1, 0, yes, no, on, or off, in any case. An empty or absent value follows the deployment mode, and any other value stops cp-api at startup.
Set the required variables in .env, then recreate cp-api:
docker compose up -d api
Email
cp-api sends invitation emails, password reset emails, and set-password links through an SMTP relay. Email is off until AISIX_CLOUD_SMTP_HOST is set. See Configure Email (SMTP) for the behavior of each setting.
| Variable | Purpose |
|---|---|
AISIX_CLOUD_SMTP_HOST | Relay host name. Empty turns email off. |
AISIX_CLOUD_SMTP_TLS | starttls (default), smtps, or none. |
AISIX_CLOUD_SMTP_PORT | Relay port. Defaults to 587, 465, or 25 according to the TLS mode. |
AISIX_CLOUD_SMTP_FROM | Sender address. Required when the host is set. |
AISIX_CLOUD_SMTP_USERNAME, AISIX_CLOUD_SMTP_PASSWORD | Relay credentials. Set both to authenticate, or neither to send without authenticating. |
AISIX_CLOUD_SMTP_INVITATION_LIMIT_PER_HOUR | Most invitation emails one account may send per rolling hour. 50 by default. |
Recreate cp-api after changing them:
docker compose up -d api
Audit Log Retention
cp-api deletes audit events older than the retention period once a day. The audit log in the console and the Admin API shows only what is kept. The period is set for the whole deployment, not in the console or the Admin API.
| Variable | Purpose |
|---|---|
AISIX_CLOUD_AUDIT_RETENTION_DAYS | Days an audit event is kept before it is deleted. 730 by default. 0 keeps audit events forever. Must be a whole number, 0 or greater; cp-api does not start with any other value. |
The first deletion runs when cp-api starts on a release that has this setting. If you need audit events older than 730 days, set a larger value or 0 before upgrading. Recreate cp-api after changing it:
docker compose up -d api
Dashboard and Ports
| Variable | Purpose |
|---|---|
AISIX_DASHBOARD_LOCALE | Default language of the dashboard and of the emails cp-api sends, used when neither the language picker, the organization's language, nor the browser's language names one. Supported values are en and zh. |
AISIX_CLOUD_DEFAULT_LOCALE | Optional. When set, it takes the place of AISIX_DASHBOARD_LOCALE for the dashboard and emails. |
POSTGRES_HOST_PORT | Host port binding for bundled PostgreSQL. |
API_HOST_PORT | Host port binding for cp-api, which serves the Admin API and the dashboard. |
DPM_HOST_PORT | Host port binding for dp-manager. |
Prefix a host port with 127.0.0.1: when the service should bind only to loopback.
Helm Values
The api7/aisix-cp chart uses Helm values instead of a Compose .env file. Add the API7 Helm repository before inspecting or installing the chart:
helm repo add api7 https://charts.api7.ai
helm repo update
To inspect every chart value, run:
helm show values api7/aisix-cp
The chart source and values are published in the api7/api7-helm-chart repository.
Every application setting of cp-api and dp-manager is an explicit Helm value. cp-api also serves the dashboard, so the dashboard settings are cp-api settings. The chart renders the values of each component into its own configuration file, stored in a ConfigMap and mounted read-only, and a change to one rolls that component's pods on helm upgrade. Secrets never enter a ConfigMap: the database passwords, master keys, SMTP password, and first administrator's password reach the pods from Kubernetes Secrets.
Each component still reads the environment variable it has always read for every setting, and an environment variable overrides the configuration file. A setting previously supplied through api.extraEnvVars or dpm.extraEnvVars therefore keeps its effect after an upgrade, and it also wins over the value that now configures it. cp-api and dp-manager log a warning at startup for each setting an environment variable overrides. Move such settings to their values below and remove the environment variable. Keep extraEnvVars for system-level variables, such as TZ.
There is no separate dashboard workload, so ui.extraEnvVars configures nothing on its own. It is kept for releases upgraded from chart 1.5.0, whose installation notes put extra sign-in origins there: an AISIX_TRUSTED_ORIGINS entry in it is still passed to cp-api, unless api.extraEnvVars sets the same name. Move such an entry to api.trustedOrigins.
Overriding a variable that the chart sets on the container itself, through api.extraEnvVars or dpm.extraEnvVars, is only a compatibility path for existing deployments, and the extraEnvVars value still wins. For a name that chart 1.5.0 rendered, the chart keeps its own entry ahead of yours, so the container lists the name twice, which Helm 4 server-side apply rejects. New installations set the value in values.yaml instead. Removing such an override from an existing release takes two helm upgrade runs; see Move Application Settings into Chart Values.
Images and Services
| Value | Purpose |
|---|---|
api.image.repository, api.image.tag | cp-api image. |
dpm.image.repository, dpm.image.tag | dp-manager image. |
api.replicaCount, dpm.replicaCount | Number of replicas for each control-plane component. |
api.affinity, dpm.affinity | Kubernetes scheduling rules used to spread replicas across nodes or failure domains. |
api.nodeSelector, dpm.nodeSelector | Node label constraints for each control-plane component. |
api.tolerations, dpm.tolerations | Kubernetes taint exceptions for each control-plane component. |
api.service.type, api.service.port, api.service.nodePort | Kubernetes Service settings for cp-api, which serves the Admin API and the dashboard. Direct NodePort connections use plain HTTP. |
dpm.service.type, dpm.service.port, dpm.service.nodePort | Kubernetes Service settings for the dp-manager mTLS endpoint. |
ui.service.type, ui.service.port, ui.service.nodePort | The <release>-ui Service kept for releases upgraded from chart 1.5.0. It now forwards to cp-api. Direct NodePort connections use plain HTTP. |
The chart renders a configured nodePort only when the corresponding Service type is NodePort. Leave the value empty to let Kubernetes allocate a port dynamically. For other Service types, the chart ignores the value.
cp-api serves the dashboard and the Admin API on the same port, so the cp-api Service is the entry point for both. Chart 1.5.0 ran the dashboard as a separate workload behind the <release>-ui Service. That Service keeps its name, type, port, and nodePort, but now selects the cp-api pods, so anything that still points at it, such as a reverse proxy, keeps working unchanged. New installations use the cp-api Service. Terminate TLS in front of either Service unless it runs only on a trusted private network.
Control Plane Metrics
cp-api exposes Prometheus metrics about the control plane's write path on a dedicated cluster-internal listener. It does not serve them from the API port used by the Admin API and dashboard, and the dashboard does not read them. Metric names use the aisix_cp_ prefix to distinguish them from gateway metrics in the same Prometheus deployment.
| Value | Purpose |
|---|---|
api.metrics.enabled | Serve Prometheus metrics from cp-api. true by default, matching the gateway chart. |
api.metrics.port | Port the metrics listener binds inside the container. Defaults to 9090. |
api.metrics.service.port | Port of the separate ClusterIP Service that exposes the metrics endpoint, so scraping never rides the API Service. Defaults to 9090. |
api.metrics.service.annotations | Extra annotations for the metrics Service, such as scrape hints for a Prometheus that discovers by annotation. |
api.metrics.serviceMonitor.enabled | Create a Prometheus Operator ServiceMonitor for the metrics Service. false by default. |
api.metrics.serviceMonitor.namespace | Namespace for the ServiceMonitor. Empty uses the release namespace. |
api.metrics.serviceMonitor.interval, api.metrics.serviceMonitor.scrapeTimeout | Scrape interval (30s by default) and timeout. An empty timeout leaves the Prometheus default. |
api.metrics.serviceMonitor.labels | Extra labels, such as the release label your Prometheus selects on. |
api.metrics.serviceMonitor.relabelings, api.metrics.serviceMonitor.metricRelabelings | Scrape-time and metric relabeling rules. |
When api.metrics.enabled is true, cp-api serves Prometheus text at /metrics on api.metrics.port. Setting the value to false leaves the metrics port unbound inside the pod, rather than only removing its Service.
api.metrics.port must differ from 8080, the port cp-api serves the Admin API and dashboard on. cp-api refuses to start if both listeners use the same address.
Two metrics are exported today, both about how much a single control-plane write projects to the data plane:
| Metric | Type | Labels | Meaning |
|---|---|---|---|
aisix_cp_outbox_rows_per_transaction | Histogram | operation, declared | Resource-outbox rows one control-plane write transaction added to the queue. operation names the declared fan-out, or none when nothing declared one. |
aisix_cp_outbox_undeclared_fanout_total | Counter | — | Write transactions that queued more outbox rows than the guard threshold without declaring a fan-out. |
Control Plane URLs
| Value | Purpose |
|---|---|
api.publicBaseURL | Browser-facing control-plane origin. Sign-in always trusts it, and invitation and password reset links point to it. Single sign-on builds its service provider URLs from it, so it must be the URL browsers actually use. When cp-api uses a NodePort, set this to the externally reachable origin at that port or the origin of the TLS reverse proxy in front of it. |
api.dpmgrBaseURL | dp-manager mTLS endpoint that AISIX gateway hosts can reach. An https:// URL such as https://dpm.example.com:7944, whose host may be a DNS name or an IP address. When dp-manager uses a NodePort, set this to its externally reachable HTTPS endpoint. The chart also passes the value to the dp-manager deployment, which issues its TLS server certificate for that host. |
api.dpImage | AISIX gateway image shown in generated AISIX Cloud gateway install snippets. Empty, the default, hands out the gateway of the same release as cp-api, docker.io/api7/aisix:<version>. |
api.corsAllowedOrigins | Browser origins allowed to call cp-api routes under /api/* cross-origin, including /api/auth/*, as a list. Empty by default, which writes no CORS headers at all. See Cross-Origin Browser Access for the accepted entries. |
api.trustedOrigins | Additional browser origins allowed to sign in, as a list of bare origins such as https://console.example.com or https://*<suffix> patterns. The api.publicBaseURL origin and its loopback twin are trusted automatically. cp-api logs and ignores an entry it cannot read as an origin. |
api.trustedProxies | Reverse proxies in front of cp-api, as a list of CIDRs such as 10.0.0.0/8, whose X-Forwarded-For header cp-api believes when it rate-limits sign-in and password reset per client. Empty by default, which treats the connecting address as the client, so behind an ingress every user shares one rate-limit budget. See Rate Limits Behind a Reverse Proxy. |
Deployment Mode and First Administrator
| Value | Purpose |
|---|---|
api.deploymentMode | on-premises, the default. The value saas is used by the API7-hosted service and is not supported for a self-hosted deployment. See Deployment Mode. |
api.domainVerification.dnsServer | DNS server, as host:port, for organization domain verification. Applies only to the saas mode. Empty, the default, uses the resolver the cp-api pod is configured with. See Deployment Mode. |
api.bootstrapAdmin.email | Email address of the first administrator. admin@example.com by default. Set it to an empty string to create no administrator. |
api.bootstrapAdmin.password | Initial password of the first administrator, 12 to 128 characters, stored in the chart's Secret. Ignored when api.bootstrapAdmin.existingSecret is set. Empty, the default, generates one. |
api.bootstrapAdmin.existingSecret, api.bootstrapAdmin.existingSecretKey | An existing Secret, and the key inside it (bootstrap-admin-password by default), that holds the initial password. |
With neither password nor existingSecret, the chart generates a random password into its own Secret, under the key bootstrap-admin-password, and keeps it across helm upgrade by reading that Secret back. The installation notes print the kubectl command that reads it.
helm template and GitOps tools that render charts themselves, such as Argo CD, cannot read the existing Secret back, so they would generate a new password on every render. For those deployments, set api.bootstrapAdmin.password or api.bootstrapAdmin.existingSecret.
The administrator is created once, on a start where the database has no users yet, and must change the password at the first sign-in. Changing these values afterwards changes nothing. See Sign In as the First Administrator.
Upgrades
| Value | Purpose |
|---|---|
api.allowUnsupportedUpgrade | Let cp-api migrate a database last run by a release older than this release supports upgrading from. false by default. Set it only after reading the startup refusal and taking a database backup, then set it back. See The Upgrade Floor Gate. |
Pricing Catalog Source
| Value | Purpose |
|---|---|
api.pricesyncURL | Model-pricing catalog URL that cp-api synchronizes from, in the models.dev api.json format. Empty uses https://models.dev/api.json. Point it at an internal mirror when cp-api has no internet access. Ignored when api.pricesyncSnapshotPath is set. |
api.pricesyncSnapshotPath | Load the catalog once at startup from this snapshot file and never fetch it. The cp-api image ships one at /etc/aisix/models-dev-snapshot.json.gz. Empty, the default, selects online synchronization, which loads that shipped snapshot when a synchronization fails while the catalog is still empty. |
Private Network Destinations
These values correspond to the Private Network Access variables. Each is unset (null) by default, which allows private, internal, and loopback destinations in on-premises mode. Set one to false to refuse them, or to true to allow them explicitly.
| Value | Purpose |
|---|---|
api.playgroundAllowPrivateIPs | Whether the dashboard playground may reach LLM endpoints on private addresses. |
api.notifyAllowPrivateURLs | Whether cp-api may send budget notifications to private addresses. |
api.mcpSpecAllowPrivateURLs | Whether the control plane may fetch an MCP server's OpenAPI document from a spec_url that resolves to a private address. Providing spec_content works either way. |
api.guardrailTestConnectionAllowInsecure | Whether the guardrail connection test may reach plain HTTP endpoints, private addresses, and hosts other than Azure. |
A release upgraded from chart 1.5.0 with helm upgrade --reuse-values still carries that chart's false defaults for api.playgroundAllowPrivateIPs and api.notifyAllowPrivateURLs as explicit values, so those two keep refusing private destinations until you clear them. See Upgrade from 1.5.x.
Email
cp-api sends invitation emails, password reset emails, and set-password links through an SMTP relay. Email is off until api.smtp.host is set. See Configure Email (SMTP) for examples and the behavior of each setting.
| Value | Purpose |
|---|---|
api.smtp.host | Relay host name. Empty, the default, turns email off. |
api.smtp.tls | starttls (default), smtps, or none. |
api.smtp.port | Relay port. 0, the default, uses 587, 465, or 25 according to the TLS mode. |
api.smtp.from | Sender address. Required when the host is set. |
api.smtp.username | Username for SMTP authentication. Set it together with a password, or leave both empty to send without authenticating. |
api.smtp.password | SMTP password, stored in the chart's Secret. Ignored when api.smtp.existingSecret is set. |
api.smtp.existingSecret, api.smtp.existingSecretKey | An existing Secret, and the key inside it (smtp-password by default), that holds the SMTP password. |
api.smtp.invitationLimitPerHour | Most invitation emails one account may send per rolling hour, across every organization. 50 by default, and at least 1. |
Audit Log Retention
cp-api deletes audit events older than the retention period once a day. The setting is not available in the console or the Admin API.
| Value | Purpose |
|---|---|
api.audit.retentionDays | Days an audit event is kept before it is deleted. 730 by default. 0 keeps audit events forever. Must be a whole number, 0 or greater; cp-api does not start with any other value. |
The first deletion runs when cp-api starts on a release that has this setting. If you need audit events older than 730 days, set a larger value or 0 in the same helm upgrade.
Secrets
| Value | Purpose |
|---|---|
secrets.masterKey | Base64-encoded 32-byte AES key used for envelope encryption. |
secrets.masterKeyID | Identifier stored with encrypted rows so the control plane can identify the wrapping key. |
secrets.retiredMasterKeys | Decrypt-only master keys kept during a master-key rotation, as a map from the key ID the key was recorded under to the base64-encoded key. IDs use lowercase letters, digits, :, and -. During rotation, move the previous active key and ID into this map, then set a new active key and ID. New values use the active key. Values encrypted before the rotation can continue to depend on a retired key until they are rewritten. |
Replace the chart's placeholder master key before installing. The chart rejects placeholder secret values.
Keep every retired master key configured and backed up. AISIX Cloud does not currently include a command that checks every stored encrypted value or moves them all to the active key. Removing a retired key while a stored value still depends on it makes that value unreadable. Do not remove a key based only on how long ago it was retired or how many new values have been written.
PostgreSQL
| Value | Purpose |
|---|---|
postgresql.builtin | Deploy the bundled PostgreSQL chart when set to true. |
postgresql.auth.password | Password for the bundled chart's configured PostgreSQL user. The chart requires a non-placeholder value even when applications connect as the postgres user. |
postgresql.auth.postgresPassword | PostgreSQL superuser password. The chart uses this for control-plane connections by default. |
postgresql.auth.usePostgresUserForAppConnections | Use the postgres user for control-plane connections. The default is true. |
postgresql.auth.existingSecret | Existing Kubernetes Secret for bundled PostgreSQL credentials. |
externalDatabase.* | Top-level values for an existing PostgreSQL database when postgresql.builtin=false. |
externalDatabase.sslmode | libpq sslmode for the external database connection, such as require or verify-full. The default is disable. |
externalDatabase.sslRootCert.existingSecret | Existing Secret holding the PEM CA bundle that issued the database server's certificate. cp-api and dp-manager use it to verify the server. Empty, the default, leaves verification to the image's system trust store. See Trust a Private Database CA. |
externalDatabase.sslRootCert.key | Key in that Secret holding the CA bundle. The default is ca.crt. |
The chart builds each postgres:// connection URL without its password. Each component reads the password from a Kubernetes Secret and percent-encodes it into the URL at startup, so the password may contain characters such as +, /, and =.
Dashboard Language
| Value | Purpose |
|---|---|
ui.defaultLocale | Default language of the dashboard and of the emails cp-api sends. Supported values are en and zh, and the default is en. It is the fallback, used when neither the language picker, the organization's language, nor the browser's language names English or Chinese. See Console Language. |
Cross-Origin Browser Access
AISIX_CLOUD_CORS_ALLOWED_ORIGINS and api.corsAllowedOrigins take the same entries. A normal installation needs neither: cp-api serves the APIs and the dashboard, so the browser has one origin and nothing is cross-origin. Populate the setting only to let a page served from somewhere else call /api/* directly. The allowlist covers both Admin API routes and the sign-in routes under /api/auth/*.
If users sign in from that origin, add it to the trusted sign-in origins as well: AISIX_TRUSTED_ORIGINS for Docker Compose, or api.trustedOrigins for Helm. CORS lets the browser reach the routes. The trusted-origin setting lets cp-api accept sign-in and other session-authenticated changes from that origin.
With Helm, add the dashboard origin to both settings:
api:
corsAllowedOrigins:
- https://dashboard.example.com
# Required when users sign in from this origin.
trustedOrigins:
- https://dashboard.example.com
Each entry takes one of two forms:
- A bare origin,
https://hostorhttps://host:port, written the way a browser serializes it in anOriginheader. Lowercase scheme and host, no path, no query, no fragment, no trailing slash and no trailing dot; the scheme's default port omitted, and a port written without leading zeros. An internationalized name is written in its punycode form, an IPv6 address in the bracketed form a browser sends, and a host whose last label is numeric must already be a dotted-quad IPv4 address. Onlyhttpsis accepted, except onlocalhost,127.0.0.1and::1, wherehttpis also accepted. - A suffix pattern,
https://*followed by a host suffix, for a dashboard whose hostname changes per deployment. The suffix starts with.or-, names at least three labels, and carries no port, path, query, fragment or trailing dot. It is matched as a byte suffix, not a DNS boundary, so it bounds a typo rather than guaranteeing that nobody else can claim a matching name on a shared hosting domain.
A bare * is refused, and so is any entry that could never equal a browser's Origin. cp-api refuses to start when an entry does not match this grammar, naming the entry's position and the rule it broke. Responses to an allowed origin never carry Access-Control-Allow-Credentials, so a page on another origin cannot send a signed-in user's session cookie with its requests.
The chart applies the same grammar at render time that cp-api applies at startup, so a value the chart accepts is one the control plane starts with.