Remove public Gitea NodePort side door
All checks were successful
Forge Runner Smoke / compatibility-smoke (push) Successful in 0s

This commit is contained in:
2026-06-14 02:26:59 +02:00
parent a1b55776fa
commit 9c4b400cb6
9 changed files with 124 additions and 9 deletions

View File

@@ -7,6 +7,8 @@ GITEA_CHART ?= gitea-charts/gitea
GITEA_VALUES ?= helm/gitea-values.sops.yaml
GITEA_REGISTRY_VALUES ?= helm/gitea-registry-values.yaml
GITEA_INGRESS ?= manifests/gitea-ingress.yaml
GITEA_HTTP_SERVICE ?= gitea-http
GITEA_SSH_SERVICE ?= gitea-ssh-nodeport
GITEA_DB_CLUSTER ?= gitea-db
GITEA_DB_NAMESPACE ?= databases
REGISTRY_DOCS ?= docs/gitea-container-registry.md docs/gitea-package-registry.md
@@ -89,7 +91,8 @@ gitea-ingress-deploy: ## Apply the public Gitea HTTPS ingress
gitea-status: ## Read-only status for current Gitea runtime and database
kubectl get pods -n $(GITEA_NAMESPACE) -l app.kubernetes.io/instance=$(GITEA_RELEASE)
kubectl get svc -n $(GITEA_NAMESPACE) $(GITEA_RELEASE) --ignore-not-found
kubectl get svc -n $(GITEA_NAMESPACE) $(GITEA_HTTP_SERVICE) --ignore-not-found
kubectl get svc -n $(GITEA_NAMESPACE) $(GITEA_SSH_SERVICE) --ignore-not-found
kubectl get ingress -n $(GITEA_NAMESPACE) $(GITEA_RELEASE) --ignore-not-found
@if kubectl cnpg status $(GITEA_DB_CLUSTER) -n $(GITEA_DB_NAMESPACE) >/dev/null 2>&1; then \
kubectl cnpg status $(GITEA_DB_CLUSTER) -n $(GITEA_DB_NAMESPACE); \

View File

@@ -117,7 +117,8 @@ The Fabric graph declarations for forge capabilities and edges live in
- Implementation: repository contract, registry docs, initial operating
contracts, deploy-capable Gitea files, and operator targets are present.
- Stability: emerging but now live-facing; forge owns the reviewed public
Gitea HTTPS ingress for the web UI, package registry, and OCI registry.
Gitea HTTPS ingress for the web UI, package registry, and OCI registry. Raw
node IP HTTP access is not part of the supported forge surface.
- Usage: canonical reference point for forge and registry responsibilities
currently transitioning out of `railiance-apps`.

View File

@@ -80,7 +80,7 @@ Observed on 2026-06-07:
| live runner process | PID `5911` after activation |
| registration file | `/root/.runner`, mode `0644`, owner `root:root` |
| registration name | `haskelseed` |
| registration address | `http://92.205.130.254:32166` |
| historical registration address | `http://92.205.130.254:32166` before the public NodePort was retired under `FORGE-WP-0005` |
| registration labels before activation | `haskelseed:host`, `linux:host`, `x86_64:host` |
| registration labels after activation | `self-hosted:host`, `haskelseed:host`, `linux:host`, `linux_amd64:host`, `x86_64:host`, `container-build:host`, `registry-publish:host` |
| ephemeral | `false` |
@@ -146,8 +146,8 @@ Run from an operator host with registry access:
```bash
for tag in 91037a4 ae9e497 fa96fb8 7cc3173 latest; do
skopeo inspect --tls-verify=false \
"docker://92.205.130.254:32166/coulomb/inter-hub:${tag}" \
skopeo inspect \
"docker://gitea.coulomb.social/coulomb/inter-hub:${tag}" \
--format "${tag} {{.Name}} {{.Digest}}"
done
```

View File

@@ -10,6 +10,8 @@ Use `gitea.coulomb.social` as the approved forge and registry host. The public
ingress serves the Gitea web route at `https://gitea.coulomb.social/`, the OCI
registry route at `/v2`, and the Python package route at `/api/packages`. The
`/v2` route returns the OCI registry authentication challenge over HTTPS.
Do not use raw node IP HTTP ports for web or registry traffic; the Gitea HTTP
Service is internal-only and the public standard is the HTTPS host.
Registry-specific Gitea settings are carried in
`helm/gitea-registry-values.yaml`, a non-secret overlay applied after the SOPS

View File

@@ -17,6 +17,7 @@ reconcile the Gitea Helm release with `helm/gitea-registry-values.yaml` so
Status on 2026-06-13: the root web route returns `200`, live `ROOT_URL` is
`https://gitea.coulomb.social/`, and package artifact links render HTTPS URLs.
Raw node IP HTTP access is not a supported package or web entry point.
## Python Packages

View File

@@ -57,6 +57,10 @@ curl -i https://gitea.coulomb.social/v2/
curl -i https://gitea.coulomb.social/api/packages/coulomb/pypi/simple/
```
The raw node IP HTTP NodePort is intentionally not part of the public health
surface. Treat any reachable `http://<node-ip>:<gitea-nodeport>/` web route as
a regression to close, not as an alternate supported endpoint.
Git SSH:
- If a Git SSH endpoint is published, verify it with a read-only `git ls-remote`

View File

@@ -1,4 +1,11 @@
# Non-secret Gitea registry settings layered after the SOPS values file.
# Non-secret Gitea public endpoint and registry settings layered after the SOPS
# values file.
service:
http:
# Public web/API access is provided by manifests/gitea-ingress.yaml.
# Keep the Service internal so the raw node IP:port path is not a
# supported or reachable Gitea entry point.
type: ClusterIP
gitea:
config:
packages:

View File

@@ -20,21 +20,21 @@ spec:
pathType: Prefix
backend:
service:
name: gitea
name: gitea-http
port:
number: 3000
- path: /v2
pathType: Prefix
backend:
service:
name: gitea
name: gitea-http
port:
number: 3000
- path: /
pathType: Prefix
backend:
service:
name: gitea
name: gitea-http
port:
number: 3000
tls:

View File

@@ -0,0 +1,97 @@
---
id: FORGE-WP-0005
type: workplan
title: "Remove public Gitea NodePort side door"
domain: railiance
repo: railiance-forge
status: finished
owner: codex
topic_slug: railiance
planning_priority: high
created: "2026-06-14"
updated: "2026-06-14"
state_hub_workstream_id: "d6af707c-d9b1-463b-b24e-b384c5fb390d"
---
# Remove public Gitea NodePort side door
## Context
After `FORGE-WP-0004`, `https://gitea.coulomb.social/` is the canonical public
Gitea endpoint. The legacy `default/gitea` Service still exposed HTTP through
NodePort `32166`, which made `http://92.205.130.254:32166/` look like a second
Gitea entry point. It reached the same pod and database, but it bypassed the
canonical HTTPS host and created operator confusion.
## T01 - Make the HTTP Service internal-only
```task
id: FORGE-WP-0005-T01
status: done
priority: high
state_hub_task_id: "1ab4f7d0-0eef-4618-84d9-a84d72db9629"
```
Set the non-secret Gitea Helm overlay to `service.http.type: ClusterIP` so the
chart-supported `gitea-http` Service stays internal-only and the web/API surface
is only public through the forge-owned HTTPS ingress. Keep Git SSH exposure
separate and unchanged.
## T02 - Reconcile live Gitea and verify the side door is gone
```task
id: FORGE-WP-0005-T02
status: done
priority: high
state_hub_task_id: "34a9759e-10f1-4202-b8e9-443265495022"
```
Apply a pinned chart `--reuse-values` Helm reconciliation that keeps the
chart-supported HTTP service internal-only while preserving the existing Gitea
app version and HTTPS `ROOT_URL`. Move the ingress backend to `gitea-http`, then
delete the legacy `default/gitea` NodePort Service because it is no longer part
of the current chart's supported public endpoint model.
Verify:
- `default/gitea` is absent and `default/gitea-http` is internal-only;
- `http://92.205.130.254:32166/` is no longer reachable;
- `https://gitea.coulomb.social/` still returns `200`;
- `/api/v1/version` still returns the live Gitea version;
- `/v2/` still returns the OCI authentication challenge;
- the package-specific PyPI simple index for `issue-core` still returns `200`.
Completed on 2026-06-14. A pinned Helm `--reuse-values` reconciliation kept
chart `gitea-12.5.0`, app `1.25.4`, and
`gitea.config.server.ROOT_URL=https://gitea.coulomb.social/` while setting
`service.http.type=ClusterIP`. The forge ingress backend was moved from the
legacy `gitea` Service to the chart-supported internal `gitea-http` Service,
then the legacy `default/gitea` NodePort Service was deleted.
Verification evidence:
- `kubectl get svc -n default -l app.kubernetes.io/instance=gitea` lists
`gitea-http` as `ClusterIP`, `gitea-ssh` as `ClusterIP`, and
`gitea-ssh-nodeport` for Git SSH only; the legacy `gitea` Service is absent;
- `http://92.205.130.254:32166/` timed out;
- `https://gitea.coulomb.social/` returned `200`;
- `https://gitea.coulomb.social/api/v1/version` returned `200`;
- `https://gitea.coulomb.social/v2/` returned `401`, preserving the OCI auth
challenge;
- `https://gitea.coulomb.social/api/packages/coulomb/pypi/simple/issue-core/`
returned `200`.
## T03 - Sync State Hub and record closure evidence
```task
id: FORGE-WP-0005-T03
status: done
priority: medium
state_hub_task_id: "0f9f6b29-aeef-4558-a5f8-d1039a136224"
```
Run State Hub consistency sync for `railiance-forge`, record a progress note,
and keep the repo docs clear that raw HTTP NodePort access is not a supported
Gitea entry point.
Completed on 2026-06-14 after live verification.