Service access¶
Hive splits traffic into internal and public by hostname. This gives safe defaults: a new service is not on the open internet until you explicitly expose it.
TL;DR¶
| Where the service is reachable | Who can reach it | When to use |
|---|---|---|
Hive domain ({name}.{namespace}.knative[-staging].svcik.org) |
Corporate network + a few trusted external networks | Internal services, dev/preview, service-to-service APIs |
customDomains (api.example.com etc.) |
Anyone | Services consumed by external users/systems |
A Hive domain always exists — it is created automatically. customDomains are opt-in via .hive.yml.
Internal: hive domains¶
Every service automatically gets a URL of the form:
https://{name}.{namespace}.knative-staging.svcik.org # staging
https://{name}.{namespace}.knative.svcik.org # production
Access to that URL is only allowed from:
- Corporate network — IP allowlist is synchronised from the corporate api-sec (offices, VPN, infrastructure).
- Cloudflare (v4/v6 ranges) — for traffic that goes through CF in front of customDomains.
- Anthropic (
160.79.104.0/21,2607:6bc0::/48) — for outbound from Claude (e.g. MCP tool calls).
Requests from any other IP are rejected with 403 RBAC: access denied at the Istio gateway. They never reach the container.
This is not a private network
Hive domains are still reachable from the public internet — the IP filter just rejects anything outside the listed networks. This is a practical "internal", not Kubernetes-grade network isolation (no mTLS, no NetworkPolicy at the service-mesh layer). For genuinely sensitive things rely on authn/authz inside the application as well.
Public: customDomains¶
To make a service reachable from outside the corporate network, add customDomains: to .hive.yml:
After deploy:
- Hive creates a
DomainMappingper domain. - cert-manager issues a TLS certificate via Let's Encrypt (first time: up to 1–2 minutes).
- Requests to
api.example.compass without the IP filter — regardless of source. - The hive domain for the same service (
my-public-api.{namespace}.knative...svcik.org) remains internal.
DNS¶
Create a CNAME (or A record) at your DNS provider pointing at the external gateway:
Ask the platform team for the exact target hostname.
Behaviour¶
| Request | Source inside allowlist | Source outside allowlist |
|---|---|---|
https://my-svc.my-team.knative-staging.svcik.org/ |
200 OK | 403 |
https://api.example.com/ (customDomain) |
200 OK | 200 OK |
So the same service answers on two URLs with different access rules.
How it works¶
Under the hood is hive-gatekeeper, a small controller in hive-core. Every 5 minutes it:
- Fetches the corporate IP allowlist from api-sec.
- Merges in static / dynamic CIDRs from a ConfigMap (Cloudflare, Anthropic, etc.).
- Reads all
DomainMappingresources in the cluster (= customDomains) into a separate allow-host list. - Rewrites two
AuthorizationPolicyobjects onGateway/eg-externalinenvoy-gateway-system: hive-ip-allowlist—ALLOW from ipBlocks ... when host ∈ *.knative.svcik.org | *.knative-staging.svcik.orghive-customdomain-allow—ALLOW from any when host ∈ <customDomains>
Anything that matches neither rule is denied (Istio default-deny when at least one ALLOW policy exists).
Adding a trusted network¶
If you need to extend the IP allowlist (a new partner, another cloud provider):
- If the source publishes a public URL with CIDRs in plaintext (Cloudflare style) — add it to
sources:in thehive-gatekeeper-sourcesConfigMap (namespacehive-core). It will be picked up on the next tick. - If there is no machine-readable endpoint — add the CIDRs statically under
static:in the same ConfigMap.
data:
sources.yaml: |
static:
- 160.79.104.0/21
- 2607:6bc0::/48
sources:
- name: cloudflare-v4
url: https://www.cloudflare.com/ips-v4
Changes apply without a pod restart — kubelet propagates the updated ConfigMap through the mounted volume.
Common gotchas¶
Service is Healthy but unreachable from outside¶
You are most likely calling it from a home/mobile IP. The hive domain will reject. Check:
Options:
- If the service is meant to be public — add
customDomains:and call it by that name. - If it's internal — connect via VPN / from the office.
403 on a customDomain through Cloudflare proxy¶
Cloudflare can hide the client's IP. If the customDomain is configured without proxying (Cloudflare DNS only), the request arrives with the client's IP — hive-customdomain-allow still passes it (no ipBlocks filter there). If with proxying — it arrives from a Cloudflare IP, which is also in the allowlist (via the cloudflare-v4/v6 sources). So 403 on a customDomain is not normal; first thing to check is whether the DomainMapping actually exists: kubectl get domainmapping -A.
Next¶
.hive.ymlreference —customDomains:and related fields- Troubleshooting — other classes of problems