Skip to content

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:

name: my-public-api
port: 8080
customDomains:
  - api.example.com
  - app.example.com

After deploy:

  1. Hive creates a DomainMapping per domain.
  2. cert-manager issues a TLS certificate via Let's Encrypt (first time: up to 1–2 minutes).
  3. Requests to api.example.com pass without the IP filter — regardless of source.
  4. 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:

api.example.com.   CNAME   external-gateway.svcik.org

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:

  1. Fetches the corporate IP allowlist from api-sec.
  2. Merges in static / dynamic CIDRs from a ConfigMap (Cloudflare, Anthropic, etc.).
  3. Reads all DomainMapping resources in the cluster (= customDomains) into a separate allow-host list.
  4. Rewrites two AuthorizationPolicy objects on Gateway/eg-external in envoy-gateway-system:
  5. hive-ip-allowlistALLOW from ipBlocks ... when host ∈ *.knative.svcik.org | *.knative-staging.svcik.org
  6. hive-customdomain-allowALLOW 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):

  1. If the source publishes a public URL with CIDRs in plaintext (Cloudflare style) — add it to sources: in the hive-gatekeeper-sources ConfigMap (namespace hive-core). It will be picked up on the next tick.
  2. 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:

curl -v https://my-svc.my-team.knative-staging.svcik.org/
# 403 RBAC: access denied

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