# Networking

The **RENU** and **ACE Uganda** Network teams are responsible for the overall production and testing network architecture, including:

- VLAN and subnet configuration

- Network architecture for the Kubernetes control plane and worker nodes

- Firewall configuration and IPv4 NAT mappings

[CORTEX-meta](https://github.com/ResearchDataCom/cortex-meta) controls the networking architecture within the Kubernetes cluster to which CORTEX runs as a set of Kubernetes workloads that are reached through a single
cluster ingress.

External traffic enters through [Emissary-ingress](https://www.getambassador.io/docs/emissary)
TLS certificates are issued automatically by [cert-manager](https://cert-manager.io/),
and public hostnames are published by [external-dns](https://kubernetes-sigs.github.io/external-dns/).
Only the web-facing components are exposed publicly; the directory and database
are reachable inside the cluster only.

## Ingress and routing

Each public component is fronted by an Emissary `Host` and `Mapping` pair. The
`Host` declares the external hostname and its TLS secret; the `Mapping` routes
requests for that hostname to the component's in-cluster `Service`. These
routing resources live in the `emissary` namespace, while the Services they
point at live in the CORTEX release namespace.

:::{admonition} Guidance
All HTTP requests are redirected to HTTPS (`requestPolicy.insecure: Redirect`).

Hostnames are configurable per component under `Proxy.hostname`,
`Discovery.hostname`, and `Registry.hostname` in `values.yaml`.
:::

## TLS certificates

cert-manager provisions certificates automatically:

- **Public HTTPS certificates** are issued by the `letsencrypt-production`
  `ClusterIssuer` (configurable via each component's `cert-issuer` value) and
  mounted by the fronting Apache container for TLS termination.
- **Internal SAML signing/encryption certificates** (the Shibboleth and SATOSA
  service-provider certs) are long-lived, self-signed certificates issued by
  per-component `Issuer` resources. They secure federation trust, not browser
  traffic.

## DNS

The `Host` resources are annotated so that external-dns publishes their
hostnames to the cluster's DNS provider. Point the `cortex.ug` domain (or your
own) at the cluster's ingress, and the per-component records are managed for
you.

## Internal services

Components talk to each other over standard Kubernetes `Service` DNS names of
the form `<service>.<namespace>.svc.cluster.local`.

| Service     | Ports    | Purpose                                          |
| ----------- | -------- | ------------------------------------------------ |
| `httpd`     | 80, 443  | Apache reverse proxy in front of SATOSA          |
| `satosa`    | 8000     | Configurable proxy for translating between authentication protocols |
| `discovery` | 80, 443  | Home-realm discovery                       |
| `registry`  | 80, 443  | COmanage Registry                                |
| `ldap`      | 389, 636 | Directory service (LDAP / LDAPS)                 |

The `satosa` service is internal only — it is reached exclusively by the
`httpd` proxy, never directly from outside the cluster.

## Directory service

The LDAP directory is exposed as a `ClusterIP` service on `389` (LDAP) and
`636` (LDAPS). It is **not** routed through Emissary and has no public
hostname; clients connect over LDAPS at
`ldap.<namespace>.svc.cluster.local:636` using the CA published in the
directory's TLS secret.

## Database

Registry stores its data in a PostgreSQL cluster managed by
[CloudNativePG](https://cloudnative-pg.io/). Registry connects to the
read-write endpoint `registry-db-rw` on port `5432` inside the cluster. The
database is never exposed outside the cluster.
