Files
mesh-catalog/modules/gitea/module.json
T
jschoubben c2353fc0a6 gitea: the internal-API refusal is part of the route, not a file beside the proxy
The 2026-09-12 incident response blocked /api/internal by hand in the
predecessor's dynamic directory, with a note that its durable home is the
mesh's routing. A route carries the policy applied to a request (ADR
0108), so the refusal now travels with the grant: route-proxy enforces
it on both the public name and the internal alias the moment it serves
this route, and the adapter skips it aloud (no port, nothing to write)
while the predecessor's own file still stands. The hand-authored file
retires with the proxy it configures.
2026-09-25 20:51:44 +02:00

224 lines
5.9 KiB
JSON

{
"module": "gitea",
"version": "1",
"requires": [
"postgres-database",
"route",
"secret"
],
"contributes": {
"postgres-database": {
"name": "gitea"
},
"route": {
"web": {
"label": "git",
"port": 3000
},
"internal-api-refused": {
"label": "git",
"path": "/api/internal",
"deny": true,
"priority": 100000
}
}
},
"binds": {
"postgres-database": "/var/lib/gitea/database.json",
"route": "/var/lib/gitea/route.json"
},
"secrets": {
"postgres-database": "/var/lib/gitea/database.secret",
"secret": {
"internal-token": "/var/lib/gitea/internal-token.secret",
"admin": "/var/lib/gitea/admin.secret"
}
},
"capabilities": [
"container-runtime"
],
"emits": [
"module.gitea.repo.created",
"module.gitea.issue.opened",
"module.gitea.pull.merged"
],
"listens": [
{
"port": 3000,
"protocol": "tcp",
"from": "mesh",
"why": "the forge, over http"
},
{
"port": 22,
"protocol": "tcp",
"from": "mesh",
"why": "git over ssh, gitea's own unmodified sshd. Published on the machine's own side at 222, the mesh's fixed public convention — not 22, which the machine's own daemon holds and a module does not take"
}
],
"serves": {
"package-registry": {
"scheme": "http",
"port": 3000,
"npm-path": "/api/packages/novox/npm/"
}
},
"receives": {
"package-registry": "/var/lib/gitea/grants/mesh.json"
},
"grants": {
"package-registry": "/var/lib/gitea/grants"
},
"own-secrets": {
"broker": "/var/lib/mesh/gitea/broker"
},
"resources": [
{
"id": "mesh-state",
"type": "directory",
"path": "/var/lib/mesh/gitea",
"mode": "0700"
},
{
"id": "runtime-state",
"type": "directory",
"path": "/var/lib/mesh/gitea/state",
"mode": "0700"
},
{
"id": "state",
"type": "directory",
"path": "/var/lib/gitea",
"mode": "0700"
},
{
"id": "grants",
"type": "directory",
"path": "/var/lib/gitea/grants",
"mode": "0700"
},
{
"id": "server-env",
"type": "file",
"path": "/var/lib/gitea/server.env",
"mode": "0600",
"content": "GITEA__security__INTERNAL_TOKEN=${secret:internal-token}\nGITEA__database__DB_TYPE=postgres\nGITEA__database__HOST=${bound:postgres-database:at}:${bound:postgres-database:port}\nGITEA__database__NAME=${bound:postgres-database:as}\nGITEA__database__USER=${bound:postgres-database:as}\nGITEA__database__PASSWD=${secret:postgres-database}\n"
},
{
"id": "data",
"type": "directory",
"path": "/services/gitea/gitea",
"mode": "0700",
"owner": "1000:1000"
},
{
"id": "server",
"type": "container",
"name": "gitea",
"image": "gitea/gitea@sha256:87a67ee09d3ae0d1df5fda5dcda3e2a1f9236a45b0a59025d6e00e46adc43bef",
"env": {
"DB_TYPE": "postgres",
"USER_UID": "1000",
"USER_GID": "1000"
},
"env-file": [
"/var/lib/gitea/server.env"
],
"ports": [
"3000",
"222:22"
],
"volumes": [
"/services/gitea/gitea:/data"
],
"secrets-in-environment": "gitea honours GITEA__database__PASSWD__FILE and GITEA__security__INTERNAL_TOKEN__FILE; convertible, awaiting a bed that proves it"
},
{
"id": "admin-bootstrap",
"type": "container",
"name": "mesh-gitea-admin",
"image": "gitea/gitea@sha256:87a67ee09d3ae0d1df5fda5dcda3e2a1f9236a45b0a59025d6e00e46adc43bef",
"run-once": true,
"env": {
"USER_UID": "1000",
"USER_GID": "1000",
"MESH_GITEA_ADMIN_USER": "mesh-admin"
},
"env-file": [
"/var/lib/gitea/server.env"
],
"volumes": [
"/services/gitea/gitea:/data",
"/var/lib/gitea/admin.secret:/run/secrets/admin:ro"
],
"args": [
"/bin/sh",
"-c",
"su-exec git gitea admin user create --admin --username \"$MESH_GITEA_ADMIN_USER\" --email mesh-admin@localhost --password \"$(cat /run/secrets/admin)\" --must-change-password=false || true"
],
"secrets-in-environment": "gitea honours GITEA__database__PASSWD__FILE and GITEA__security__INTERNAL_TOKEN__FILE; convertible, awaiting a bed that proves it"
},
{
"id": "runtime-config",
"type": "file",
"path": "/var/lib/mesh/gitea/config.json",
"mode": "0600",
"content": "{}\n",
"merge": "json"
},
{
"id": "runtime",
"type": "container",
"name": "mesh-gitea",
"network": "host",
"volumes": [
"/var/lib/mesh/gitea/broker:/run/secrets/broker:ro",
"/var/lib/mesh/gitea/config.json:/run/config/config.json:ro",
"/var/lib/gitea/grants:/var/lib/gitea/grants:ro",
"/var/lib/gitea/admin.secret:/run/secrets/admin:ro",
"/var/lib/mesh/gitea/state:/run/state"
],
"env": {
"MESH_BROKER_FILE": "/run/secrets/broker",
"MESH_GITEA_URL": "http://127.0.0.1:${port:3000}",
"MESH_GITEA_CONFIG_FILE": "/run/config/config.json",
"MESH_GITEA_ADMIN_USER": "mesh-admin",
"MESH_GITEA_ADMIN_PASSWORD_FILE": "/run/secrets/admin",
"MESH_GITEA_STATE_DIR": "/run/state",
"MESH_RECEIVES": "/var/lib/gitea/grants/mesh.json"
},
"artifact": "runtime",
"restart-on": [
"runtime-config"
]
}
],
"provides": [
{
"name": "package-registry",
"scope": "mesh"
}
],
"build": {
"on": [
{
"arg": "BUILD_BASE",
"module": "mesh-tools",
"artifact": "build"
},
{
"arg": "RUNTIME_BASE",
"module": "mesh-tools",
"artifact": "runtime"
}
],
"artifacts": [
{
"name": "runtime",
"kind": "image",
"from": "Dockerfile"
}
]
}
}