A nullplatform service that manages dynamic exposure of application endpoints through public and private domains. It translates high-level route declarations into native Kubernetes resources using Istio — HTTPRoutes, AuthorizationPolicies, and RequestAuthentication — all without developers needing to touch YAML.
Developers declare which HTTP routes they want to expose, which nullplatform scope backs each route, and which user groups are allowed to call it. The service handles the rest:
- Creates HTTPRoutes (Kubernetes Gateway API v1) pointing to the right backend service
- Creates AuthorizationPolicies enforcing group-based access control
- Creates RequestAuthentication resources validating JWT tokens (Cognito) or delegating to AVP
Route visibility is resolved automatically from the scope's own visibility attribute (external → public gateway, internal → private gateway).
AUTH_TYPE |
Mechanism |
|---|---|
aws-cognito |
Istio validates Cognito JWT; AuthorizationPolicies check cognito:groups claims |
aws-avp |
Amazon Verified Permissions policy store controls access |
When creating or updating the service, developers configure one or more routes:
| Field | Description |
|---|---|
| Verbs | HTTP methods (GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS) |
| Path | Route path. Supports exact (/api/users), parameterized (/api/users/{id}), and wildcard (/api/users/*) |
| Scope | nullplatform scope slug that backs this route |
| Authorized Groups | Comma-separated list of groups allowed to call this route (e.g. admin, read-only) |
Auth configuration is not part of the developer UI — it is set once at the infrastructure level via agent environment variables (see below).
- A running nullplatform agent with
kubectlaccess to the cluster - Istio installed with Gateway API CRDs
gateway-publicandgateway-privateGateway resources deployed
Register the service specification and notification channel in nullplatform:
module "endpoint_exposer" {
source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/service_definition?ref=<version>"
nrn = var.nrn
repository_org = "nullplatform"
repository_name = "services-endpoint-exposer"
repository_branch = "main"
service_path = "" # specs live at repo root
service_name = "Endpoint Exposer"
available_links = ["connect"]
}
module "endpoint_exposer_channel" {
source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/service_definition_agent_association?ref=<version>"
nrn = var.nrn
api_key = var.np_api_key
tags_selectors = { "owner" = "my-agent", "environment" = "{$context.service.dimensions.environment}" }
service_specification_slug = module.endpoint_exposer.service_specification_slug
repository_service_spec_repo = "nullplatform/services-endpoint-exposer"
service_path = "" # entrypoint lives at repo root
}Auth configuration is resolved at runtime from the agent's environment, not from the developer UI. Set these variables in the agent's extra_envs (Helm) or equivalent.
| Variable | Description | Example |
|---|---|---|
AUTH_TYPE |
Authorization scheme for the entire installation | aws-cognito |
INGRESS_TYPE |
Must be istio |
istio |
One variable per nullplatform environment dimension value (uppercased):
| Variable | Description | Example |
|---|---|---|
COGNITO_USER_POOL_ARN_<ENV> |
ARN of the Cognito User Pool for that environment | COGNITO_USER_POOL_ARN_PRODUCTION=arn:aws:cognito-idp:us-east-1:123456789:userpool/us-east-1_AbCdEf |
<ENV> corresponds to service.dimensions.environment uppercased (e.g. dev → DEV, production → PRODUCTION).
| Variable | Description | Example |
|---|---|---|
AVP_POLICY_STORE_ARN_<ENV> |
ARN of the Amazon Verified Permissions Policy Store | AVP_POLICY_STORE_ARN_PRODUCTION=arn:aws:verifiedpermissions::123456789:policy-store/AbCdEf |
OPA_PROVIDER_NAME |
Name of the OPA ext-authz provider in the cluster | opa-ext-authz |
| Variable | Default | Description |
|---|---|---|
PUBLIC_GATEWAY_NAME |
gateway-public |
Name of the public Istio Gateway resource |
PRIVATE_GATEWAY_NAME |
gateway-private |
Name of the private Istio Gateway resource |
GATEWAY_NAMESPACE |
gateways |
Kubernetes namespace where Gateway resources live |
module "agent" {
source = "git::https://github.com/nullplatform/tofu-modules.git//nullplatform/agent?ref=<version>"
# ... other agent config ...
extra_envs = {
INGRESS_TYPE = "istio"
AUTH_TYPE = "aws-cognito"
COGNITO_USER_POOL_ARN_DEV = "arn:aws:cognito-idp:us-east-1:123456789:userpool/us-east-1_AbCdEf"
COGNITO_USER_POOL_ARN_PRODUCTION = "arn:aws:cognito-idp:us-east-1:123456789:userpool/us-east-1_XyZwVu"
}
}On every action (create / update / delete) the service:
- Reads
AUTH_TYPEfrom the agent environment - Reads
service.dimensions.environmentfrom the action context (e.g."dev") - Uppercases and normalizes the value →
DEV - Looks up
COGNITO_USER_POOL_ARN_DEV(orAVP_POLICY_STORE_ARN_DEV) via bash indirect expansion - Fails with a clear error if the required variable is not set
This means a single agent deployment can serve multiple environments, each with its own pool/store ARN.
├── entrypoint/ # Action handler (service, link)
├── scripts/
│ ├── common/ # apply, manage_policies
│ ├── istio/ # build_context, build_httproute, process_routes, build_allow_policies,
│ │ # build_request_authentication, delete_*, fetch_provider_data, config
│ ├── np/ # update_service_results
│ └── avp/ # AVP-specific policy management (aws-avp only)
├── specs/
│ ├── service-spec.json.tpl
│ └── links/connect.json.tpl
├── templates/istio/ # Kubernetes resource templates (httproute, authorizationpolicy, request-authentication)
├── workflows/istio/ # create.yaml, update.yaml, delete.yaml, read.yaml
├── install/tofu/ # OpenTofu module for registering the service in nullplatform
├── test/ # BATS test suite
└── container-scope-override/ # Deployment templates for override scope agent
./test/run-tests.shTests use BATS and cover HTTPRoute generation, AuthorizationPolicy creation, context building, and apply/cleanup flows.
# HTTPRoutes
kubectl get httproutes -n nullplatform
# AuthorizationPolicies
kubectl get authorizationpolicies -n gateways
# RequestAuthentication (Cognito JWT rules)
kubectl get requestauthentication -n gateways