Skip to main content
Version: Next

API Platform Gateway Extension

A Helm chart to deploy and auto-register the unified API Platform Gateway for the Agent Management Platform.

helm install amp-api-platform-gateway-extension oci://ghcr.io/wso2/helm-charts/wso2-amp-api-platform-gateway-extension \
--namespace <namespace> --create-namespace \
--values my-values.yaml

agentManager​

ParameterDescriptionTypeDefault
agentManagerAgent Manager API connection details (used by bootstrap job to register gateway)object
agentManager.apiUrlPublic API URL (port 8080 = JWT-authenticated API)string"http://amp-api.wso2-amp.svc.cluster.local:9000/api/v1"
agentManager.orgNameOrganization name in Agent Manager (must match Thunder OU handle)string"default"
agentManager.idpThunder IDP for obtaining a JWT to call Agent Manager APIobject
agentManager.idp.tokenUrlToken endpoint the gateway requests its access token from.string"http://amp-thunder-extension-service.amp-thunder.svc.cluster.local:8090/oauth2/token"
agentManager.idp.clientIdOAuth 2.0 client ID for the gateway's control-plane calls.string"amp-api-client"
agentManager.idp.clientSecretOAuth 2.0 client secret. Prefer an existing Secret in real deployments. Allowed values: Prefer existingSecret; only set this for local/dev use.string"amp-api-client-secret"
agentManager.idp.existingSecretReference an existing secret for IDP credentials (recommended for production). When set, clientId and clientSecret above are ignored.string""
agentManager.idp.existingSecretClientIdKeyKey within the existing Secret holding the client ID.string"client-id"
agentManager.idp.existingSecretClientSecretKeyKey within the existing Secret holding the client secret.string"client-secret"

apiGateway​

ParameterDescriptionTypeDefault
apiGatewayRuntime configuration for the API Platform Gateway.object
apiGateway.namespaceNamespace where the APIGateway CR is created. Must be the same namespace where the gateway-operator is watching. For per-org-env namespace isolation set this to "<org>-<env>" (add-environment.sh passes it via --set apiGateway.namespace=...).string"openchoreo-data-plane"
apiGateway.controlPlaneControl plane connection: points to Agent Manager's gateway management port (9243)object
apiGateway.controlPlane.hostIn-cluster address of the control plane.string"amp-api-gateway-manager.wso2-amp.svc.cluster.local:9243"
apiGateway.controlPlane.tlsTLS settings for the control-plane connection.object
apiGateway.controlPlane.tls.enabledUse TLS when connecting to the control plane.booleantrue
apiGateway.controlPlane.tls.insecureSkipVerifySkip verification of the control plane's TLS certificate. True by default because the control plane serves a self-signed certificate in-cluster. Note: the template applies | default true, and Go templates treat false as empty, so setting this to false here does not currently disable it.booleantrue
apiGateway.configConfigMap containing full Helm values for the gateway Helm chart. The gateway-operator reads this and passes it when deploying the gateway stack.object
apiGateway.config.configMapNameName of the ConfigMap to create with gateway Helm values. Defaults to "<release-name>-config" if empty.string""
apiGateway.config.policyConfigurationsPolicy configurations rendered under [policy_configurations.*] in config.toml. Consumed by policies that reference ${config.policy_configurations.<section>.<key>}.object
apiGateway.config.policyConfigurations.ratelimit_v1- Rate Limiting (shared by basic-ratelimit, advanced-ratelimit, token-based-ratelimit, llm-cost-based-ratelimit) ---object
apiGateway.config.policyConfigurations.ratelimit_v1.algorithmRate-limiting algorithm used to count requests. Allowed values: "fixed-window" or "gcra".string"fixed-window"
apiGateway.config.policyConfigurations.ratelimit_v1.backendWhere counters are stored. In-memory counters are per gateway replica. Allowed values: "memory" or "redis".string"memory"
apiGateway.config.policyConfigurations.ratelimit_v1.memorySettings for the in-memory counter backend.object
apiGateway.config.policyConfigurations.ratelimit_v1.memory.max_entriesMaximum counters held in memory before eviction.integer10000
apiGateway.config.policyConfigurations.ratelimit_v1.memory.cleanup_intervalHow often expired counters are purged.string"5m"
apiGateway.config.policyConfigurations.llm_cost_ratelimit_v1- LLM Cost Based Rate Limiting (additional to ratelimit_v1) ---object
apiGateway.config.policyConfigurations.llm_cost_ratelimit_v1.cost_scale_factorFixed-point scale applied to costs so they can be counted as integers.integer1000000000
apiGateway.config.policyConfigurations.jwtauth_v1- JWT Authentication (shared by jwt-auth and mcp-auth) ---object
apiGateway.config.policyConfigurations.jwtauth_v1.keymanagersTrusted token issuers, each with its issuer URL and JWKS endpoint.arraysee values.yaml
apiGateway.config.policyConfigurations.jwtauth_v1.authheaderschemeScheme expected on the Authorization header. Empty accepts a bare token.string""
apiGateway.config.policyConfigurations.jwtauth_v1.onfailurestatuscodeHTTP status returned when authentication fails.integer401
apiGateway.config.policyConfigurations.jwtauth_v1.errormessageformatFormat of the authentication failure body.string"json"
apiGateway.config.policyConfigurations.jwtauth_v1.errormessageMessage returned when authentication fails.string"Authentication failed"
apiGateway.config.policyConfigurations.jwtauth_v1.leewayClock skew tolerated when checking token expiry.string"30s"
apiGateway.config.policyConfigurations.jwtauth_v1.allowedalgorithmsSigning algorithms accepted on incoming tokens.arraysee values.yaml
apiGateway.config.policyConfigurations.jwtauth_v1.jwkscachettlHow long a fetched JWKS is cached before refetching.string"5m"
apiGateway.config.policyConfigurations.jwtauth_v1.jwksfetchtimeoutTimeout for a single JWKS fetch.string"5s"
apiGateway.config.policyConfigurations.jwtauth_v1.jwksfetchretrycountRetries attempted when a JWKS fetch fails.integer3
apiGateway.config.policyConfigurations.jwtauth_v1.jwksfetchretryintervalWait between JWKS fetch retries.string"2s"
apiGateway.config.policyConfigurations.jwtauth_v1.validateissuerReject tokens whose issuer is not a configured key manager.booleantrue
apiGateway.config.config_tomlRaw TOML injected at the TOP of the downstream gateway chart's generated config.toml, above every [table] section (rendered as gateway.config_toml in the generated values.yaml). Use for policy "system parameters" that policies read as ${config.<key>} at root level (e.g. AWS Bedrock, Azure Content Safety, embedding providers) — TOML requires bare root keys to precede any [table] header, which is why this leads the file. Whole [table] sections work here too (tables are order-independent). Do NOT redefine a table this chart already emits below ([policy_configurations.], [controller.], [router], etc.) — TOML rejects a duplicate table and the gateway-runtime crash-loops on it. config.toml renders into a ConfigMap, not a Secret. For any secret value, supply an &#123;&#123; env "VAR" &#125;&#125; interpolation token (resolved by the policy engine at load time) instead of a literal, and inject the backing env var via apiGateway.config.systemExtraEnv below (backed by a Kubernetes Secret, never a plaintext value). Example: config_toml: | # AWS Bedrock Guardrail awsbedrock_guardrail_region = "us-east-1" awsbedrock_guardrail_id = "" awsbedrock_guardrail_version = "DRAFT" awsbedrock_access_key_id = "" awsbedrock_secret_access_key = '{{ env "APIP_GW_AWSBEDROCK_SECRET_ACCESS_KEY" }}' awsbedrock_session_token = "" awsbedrock_role_arn = "" awsbedrock_role_region = "" awsbedrock_role_external_id = "" # Azure Content Safety azurecontentsafety_endpoint = "" azurecontentsafety_key = '{{ env "APIP_GW_AZURECONTENTSAFETY_KEY" }}' # Embedding Provider (semantic-cache, semantic-prompt-guard, semantic-tool-filtering) embedding_provider = "OPENAI" embedding_provider_endpoint = "" embedding_provider_model = "text-embedding-ada-002" embedding_provider_dimension = "1536" embedding_provider_api_key = '{{ env "APIP_GW_EMBEDDING_PROVIDER_API_KEY" }}' # Vector DB (semantic-cache) vector_db_provider = "REDIS" vector_db_provider_host = "" vector_db_provider_port = "6379" vector_db_provider_username = "" vector_db_provider_password = '{{ env "APIP_GW_VECTOR_DB_PROVIDER_PASSWORD" }}' vector_db_provider_database = "" vector_db_provider_ttl = "3600" # Granite Guardian Prompt Injection granite_guardian_endpoint = "http://granite-guardian:8000" granite_guardian_model = "ibm-granite/granite-guardian-3.3-8b" granite_guardian_timeout = "10" granite_guardian_api_key = '{{ env "APIP_GW_GRANITE_GUARDIAN_API_KEY" }}' # NeMo Guard Content Safety nemoguard_endpoint = "http://nemoguard:8101" nemoguard_model = "nemoguard" nemoguard_timeout = "30" nemoguard_api_key = '{{ env "APIP_GW_NEMOGUARD_API_KEY" }}'string""
apiGateway.config.systemExtraEnvEnv vars backing any &#123;&#123; env "..." &#125;&#125; tokens used in config_toml above. config.toml is loaded by both the gateway-controller and gatewayRuntime (policy engine) pods, so each entry is rendered into BOTH controller.deployment.extraEnv and gatewayRuntime.deployment.extraEnv. Secret values should use valueFrom.secretKeyRef rather than a literal value. Example: systemExtraEnv: - name: APIP_GW_AZURECONTENTSAFETY_KEY valueFrom: secretKeyRef: name: azure-content-safety key: subscription-keyarray[]

bootstrap​

ParameterDescriptionTypeDefault
bootstrapBootstrap Job configuration The job runs as a pre-install, pre-upgrade AND pre-rollback hook, so helm rollback now runs it too and can fail (leaving the release in pending-rollback) when Agent Manager is unreachable — rollbacks could not fail before. Recovery: re-run helm rollback, or helm rollback --no-hooks to skip the job entirely.object
bootstrap.enabledRun the bootstrap job.booleantrue
bootstrap.backoffLimitRetries before the bootstrap job is marked failed.integer3
bootstrap.identityProvidersIdentity providers to mirror into Agent Manager (AMS) for this gateway. This list is the authoritative allowlist of IdPs the bootstrap job seeds via the AMS identity-provider API. It is intentionally decoupled from apiGateway.config.policyConfigurations.jwtauth_v1.keymanagers: that list is the gateway runtime's JWT-validation config (and legitimately includes the internal 'agent-manager-service' keymanager and ThunderKeyManager), whereas this list is what AMS exposes in the Security UI and as agent OAuth issuer options. Only list user-visible providers here — omit any internal/reserved keymanagers (e.g. agent-manager-service). Defaults to empty: no IdP is auto-mirrored into AMS. ThunderKeyManager stays a gateway keymanager (so deployed agents still validate Thunder-issued tokens), but is no longer registered as a visible identity provider by default — operators add IdPs on demand via the Manage Identity Provider flow. The bootstrap job seeds exactly the entries listed here, so an empty list seeds nothing. Each entry: { name, issuer, jwksUri, skipTlsVerify }.array[]
bootstrap.ttlSecondsAfterFinishedTTL after completion (seconds). 86400 = 1 dayinteger86400
bootstrap.resourcesCompute resources for the bootstrap job.object
bootstrap.resources.requestsResources reserved for the bootstrap job at scheduling time.object
bootstrap.resources.requests.memoryMemory the container requests at scheduling timestring"64Mi"
bootstrap.resources.requests.cpuCPU the container requests at scheduling timestring"50m"
bootstrap.resources.limitsMaximum resources the bootstrap job may use.object
bootstrap.resources.limits.memoryMaximum memory the container may use before it is OOM-killedstring"128Mi"
bootstrap.resources.limits.cpuMaximum CPU the container may usestring"100m"
bootstrap.podSecurityContextPod-level security settings for the bootstrap job.object
bootstrap.podSecurityContext.runAsNonRootRequire the container to run as a non-root userbooleanfalse
bootstrap.podSecurityContext.runAsUserUID the pod's containers run asinteger0
bootstrap.podSecurityContext.fsGroupSupplemental group applied to mounted volumesinteger0
bootstrap.securityContextContainer-level security settings for the bootstrap job.object
bootstrap.securityContext.runAsNonRootRequire the container to run as a non-root userbooleanfalse
bootstrap.securityContext.runAsUserUID the container runs asinteger0
bootstrap.securityContext.allowPrivilegeEscalationAllow a process to gain more privileges than its parentbooleanfalse
bootstrap.securityContext.capabilitiesLinux capabilities adjusted for the bootstrap container.object
bootstrap.securityContext.capabilities.dropLinux capabilities removed from the containerarraysee values.yaml
bootstrap.securityContext.readOnlyRootFilesystemMount the container root filesystem read-onlybooleanfalse

developmentMode​

ParameterDescriptionTypeDefault
developmentModeAPIGateway CR configuration (deployed by gateway-operator) Development modebooleantrue

gateway​

ParameterDescriptionTypeDefault
gatewayGateway registration configurationobject
gateway.nameName of the AI gateway to register in Agent Manager (lowercase alphanumeric + hyphens). Defaults to the Helm release name if empty.string""
gateway.displayNameHuman-readable display namestring"Default API Gateway"
gateway.vhostVirtual host (FQDN or IP) that the gateway is reachable on. All access is hostname-routed through kgateway — never the runtime Service directly.string"http://default-default.gateway.localhost:19080"
gateway.runtimeUrlIn-cluster base URL sandboxed agents use to reach this gateway runtime. Empty derives "http://<apiGatewayName>-gw-gateway-gateway-runtime.<apiGateway.namespace>:22893". AMS validates it: http/https, explicit port that is not 80 or 443, cluster-local host.string""
gateway.hostnameHostname for routing traffic to this gateway through kgateway. All traffic (LLM proxy, OTEL, etc.) matching this hostname on kgateway is forwarded to this gateway's runtime service. Defaults to "<environment>-<orgName>.gateway.localhost" if empty.string""
gateway.typeGateway placement role: INGRESS, EGRESS, or BOTH (must match GatewayType enum in Agent Manager API). BOTH is correct for single topology, where the chart is installed once per environment; split topology sets this explicitly on both releases from add-environment.sh. Immutable after first registration — changing it later only logs a drift warning.string"BOTH"
gateway.environmentEnvironment name in Agent Manager to associate this gateway with. The bootstrap job looks up environments by this name.string"default"
gateway.tokenSecretThe generated registration token is stored in this Kubernetes Secret. It is then referenced by the APIGateway CR spec.controlPlane.tokenSecretRef. Defaults to "<release-name>-token" if empty.object
gateway.tokenSecret.nameName of the Secret. Generated when empty.string""
gateway.tokenSecret.keyKey within the Secret holding the token.string"token"

kgateway​

ParameterDescriptionTypeDefault
kgatewaykgateway ingress the gw-route HTTPRoute attaches to. This is the shared data-plane Gateway provisioned by the OpenChoreo data-plane chart — it does NOT move when the api-platform gateway gets its own per-org-env namespace. The HTTPRoute is created here (same namespace as the Gateway) and reaches the gateway runtime Service cross-namespace via a ReferenceGrant.object
kgateway.nameName of the Gateway resource.string"gateway-default"
kgateway.namespaceNamespace containing the Gateway resource.string"openchoreo-data-plane"

kubectl​

ParameterDescriptionTypeDefault
kubectlKubectl image used in bootstrap jobobject
kubectl.imageImage providing the kubectl binary for helper jobsstring"alpine/k8s:1.32.3"