Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ permissions:
contents: read

jobs:
authority-cell-checks:
lab-checks:
runs-on: ubuntu-latest
timeout-minutes: 30
steps:
Expand Down Expand Up @@ -46,9 +46,9 @@ jobs:
run: just generate
- name: Publish checked-in metadata
run: just metadata-publish
- name: Lint authority-cell configuration
- name: Lint lab configuration
run: just lint
- name: Test authority-cell application
- name: Test lab application
run: just test
- name: Validate and package all Relay V2 projects
run: just relay-check
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/release-candidate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ jobs:
run: |
cd portal && pnpm exec playwright install --with-deps chromium
cd ../home && pnpm exec playwright install chromium
- name: Generate and validate authority-cell runtime
- name: Generate and validate lab runtime
env:
REGISTRY_STACK_SOURCE_DIR: ${{ github.workspace }}/vendor/registry-stack
run: |
Expand All @@ -114,7 +114,7 @@ jobs:
just test
just compose
just relay-check
- name: Start and smoke authority cells
- name: Start and smoke the lab stack
env:
REGISTRY_STACK_SOURCE_DIR: ${{ github.workspace }}/vendor/registry-stack
run: |
Expand All @@ -125,13 +125,13 @@ jobs:
just lifecycle-proof
just portal-live-e2e
just home-live-e2e
- name: Report authority-cell startup failure
- name: Report lab startup failure
if: failure()
run: |
project_name="$(python3 scripts/compose_project_name.py)"
docker compose --env-file versions.env --env-file .env --project-name "$project_name" -f compose.yaml ps --all
docker compose --env-file versions.env --env-file .env --project-name "$project_name" -f compose.yaml logs --no-color \
authority-audit-init mint evidence-gateway relay-issuer-readiness \
authority-audit-init mint local-edge relay-issuer-readiness \
cra-relay nia-relay mosd-relay sipf-relay nagdi-relay
- name: Record recoverable rollout phases
run: |
Expand Down Expand Up @@ -469,6 +469,6 @@ jobs:
printf -- '- %s=%s\n' "$key" "$image"
done < "$RUNNER_TEMP/solmara-release/solmara-hosted-images.env"
} >> "$GITHUB_STEP_SUMMARY"
- name: Stop authority-cell stack
- name: Stop the lab stack
if: always()
run: just down || true
2 changes: 1 addition & 1 deletion compose.coolify.signers.interior.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: solmara-lab-interior-signers

# This operator-only application is the private issuer-key boundary for the
# Interior cells. It holds only the CRA and NIA signing keys and attaches only
# Interior Evidence gateways. It holds only the CRA and NIA signing keys and attaches only
# their Transit socket directories under the shared authority state root.
x-transit-init: &transit-init
image: ${SOLMARA_TRANSIT_SIGNER_IMAGE:?set the digest-pinned Solmara Transit signer image}
Expand Down
8 changes: 4 additions & 4 deletions compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ services:
networks: [issuer-validation]
depends_on:
mint: {condition: service_started}
evidence-gateway: {condition: service_started}
local-edge: {condition: service_started}

mint-signer:
<<: *transit-signer
Expand Down Expand Up @@ -566,11 +566,11 @@ services:
networks: {runtime: {ipv4_address: 172.29.1.26}, issuer-validation: {}}
depends_on: {mint: {condition: service_started}, nagdi-secret-stager: {condition: service_completed_successfully}, authority-audit-init: {condition: service_completed_successfully}, nagdi-signer: {condition: service_healthy}, nagdi-relay: {condition: service_healthy}}

evidence-gateway:
image: ${EVIDENCE_GATEWAY_IMAGE:?versions.env must pin Caddy}
local-edge:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Remove the orphaned edge container during the rename

When a developer updates while the existing lab stack is running, Compose treats evidence-gateway as an orphan rather than recreating it as local-edge. The canonical just up and just up-esignet recipes in justfile:89-93 invoke up --force-recreate without --remove-orphans, so the old container remains bound to port 4341 and this renamed service cannot start. Docker documents --remove-orphans as removing services no longer defined in the Compose file; add that cleanup to the recipes or provide an equivalent migration step.

AGENTS.md reference: AGENTS.md:L19-L21

Useful? React with 👍 / 👎.

image: ${LOCAL_EDGE_IMAGE:?versions.env must pin Caddy}
user: "0:0"
restart: unless-stopped
ports: ["${SOLMARA_EVIDENCE_GATEWAY_PORT:-4341}:443"]
ports: ["${SOLMARA_LOCAL_EDGE_PORT:-4341}:443"]
volumes: ["./config/evidence/Caddyfile:/etc/caddy/Caddyfile:ro", "./config/evidence/local/tls:/etc/solmara-evidence/tls:ro", "caddy-data:/data", "caddy-config:/config"]
networks:
runtime:
Expand Down
11 changes: 11 additions & 0 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@
A small dated log of what changed in the visitor center and the lab topology.
Newest entry first.

## 2026-08-21 The local front door is `local-edge`

The local Compose service that terminates TLS on port 4341 was called
`evidence-gateway`, which now names something else. It is also not only an
Evidence front door: the same Caddy instance answers the Relay and Mint
hostnames the hermetic local run needs. It is now `local-edge`, pinned by
`LOCAL_EDGE_IMAGE`, and its published port is `SOLMARA_LOCAL_EDGE_PORT`. The
default port is still 4341, so a developer who never overrode
`SOLMARA_EVIDENCE_GATEWAY_PORT` has nothing to change. Nothing hosted uses
this service.

## 2026-08-20 Evidence gateways replace "cells"

Every visitor-facing surface now calls an authority's Evidence deployment an
Expand Down
2 changes: 1 addition & 1 deletion scripts/check-image-pins.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
}
SOURCE_IMAGE_KEYS = set(OFFICIAL_RUNTIME_REPOSITORIES)
PINNED_IMAGE_KEYS = {
"VOLUME_INIT_IMAGE", "EVIDENCE_GATEWAY_IMAGE", "PYTHON_STATIC_IMAGE",
"VOLUME_INIT_IMAGE", "LOCAL_EDGE_IMAGE", "PYTHON_STATIC_IMAGE",
"NODE_BUILD_IMAGE", "UV_BUILD_IMAGE",
"ESIGNET_REDIS_IMAGE", "ESIGNET_BASE_IMAGE", "ESIGNET_UI_IMAGE",
"ESIGNET_POSTGRES_IMAGE",
Expand Down
10 changes: 5 additions & 5 deletions scripts/test_image_pins.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
EVIDENCE = "ghcr.io/registrystack/evidence@sha256:" + "2" * 64
MINT = "ghcr.io/registrystack/mint@sha256:" + "3" * 64
VOLUME_INIT = "busybox@sha256:" + "4" * 64
GATEWAY = "caddy@sha256:" + "5" * 64
LOCAL_EDGE = "caddy@sha256:" + "5" * 64


def load_check_image_pins():
Expand All @@ -40,7 +40,7 @@ def setUp(self) -> None:
f"SOLMARA_EVIDENCE_IMAGE={EVIDENCE}\n"
f"SOLMARA_MINT_IMAGE={MINT}\n"
f"VOLUME_INIT_IMAGE={VOLUME_INIT}\n"
f"EVIDENCE_GATEWAY_IMAGE={GATEWAY}\n",
f"LOCAL_EDGE_IMAGE={LOCAL_EDGE}\n",
encoding="utf-8",
)
with (self.root / "versions.env").open("a", encoding="utf-8") as versions:
Expand Down Expand Up @@ -79,13 +79,13 @@ def test_source_images_must_be_required(self) -> None:
self.assertEqual(result, 1)
self.assertIn("expected a required REGISTRY_RELAY_IMAGE reference", stderr)

def test_gateway_must_be_digest_pinned(self) -> None:
versions = (self.root / "versions.env").read_text().replace(GATEWAY, "caddy:latest")
def test_local_edge_must_be_digest_pinned(self) -> None:
versions = (self.root / "versions.env").read_text().replace(LOCAL_EDGE, "caddy:latest")
(self.root / "versions.env").write_text(versions)
result, stderr = self.run_check()

self.assertEqual(result, 1)
self.assertIn("EVIDENCE_GATEWAY_IMAGE must use image@sha256", stderr)
self.assertIn("LOCAL_EDGE_IMAGE must use image@sha256", stderr)

def test_runtime_images_must_use_their_exact_official_repository(self) -> None:
versions = (self.root / "versions.env").read_text().replace(
Expand Down
8 changes: 4 additions & 4 deletions scripts/test_runtime_topology.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ def test_local_relays_use_the_v2_runtime_filesystem_contract(self) -> None:
issuer_readiness["depends_on"],
{
"mint": {"condition": "service_started"},
"evidence-gateway": {"condition": "service_started"},
"local-edge": {"condition": "service_started"},
},
)
readiness_code = issuer_readiness["command"][2]
Expand Down Expand Up @@ -276,13 +276,13 @@ def test_local_oidc_issuer_uses_an_isolated_testnet_address(self) -> None:
[{"subnet": "192.0.2.0/26", "ip_range": "192.0.2.0/27"}],
)

gateway_networks = compose["services"]["evidence-gateway"]["networks"]
edge_networks = compose["services"]["local-edge"]["networks"]
self.assertNotIn(
"mint.solmara.registrystack.org",
gateway_networks["runtime"]["aliases"],
edge_networks["runtime"]["aliases"],
)
self.assertEqual(
gateway_networks["issuer-validation"],
edge_networks["issuer-validation"],
{
"ipv4_address": "192.0.2.62",
"aliases": ["mint.solmara.registrystack.org"],
Expand Down
4 changes: 2 additions & 2 deletions versions.env
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Registry Stack v0.21.0 is the earliest release that publishes the Relay,
# Evidence, and Mint images required by the authority-cell reset. Solmara
# Evidence, and Mint images required by the authority-owned reset. Solmara
# pins v0.23.0, the current release on that line.
REGISTRY_STACK_REQUIRED_VERSION=0.23.0
REGISTRY_STACK_RELEASE_RELAY_DIGEST=734d89fa6dd11a7fe788d09b0cc2bec381de9f19b8522026158428bea93aaaa0
Expand All @@ -20,7 +20,7 @@ PYTHON_STATIC_IMAGE=python@sha256:6d43704baacd1bfbe7c295d7f13079d5d8104ed3356887
NODE_BUILD_IMAGE=node@sha256:c610fcdfb1d5b4740dd70c284ed3cb16bb857e0f7166196e36a5501df7a3aa32
UV_BUILD_IMAGE=ghcr.io/astral-sh/uv@sha256:440fd6477af86a2f1b38080c539f1672cd22acb1b1a47e321dba5158ab08864d
VOLUME_INIT_IMAGE=busybox@sha256:73aaf090f3d85aa34ee199857f03fa3a95c8ede2ffd4cc2cdb5b94e566b11662
EVIDENCE_GATEWAY_IMAGE=docker.io/library/caddy@sha256:4c6e91c6ed0e2fa03efd5b44747b625fec79bc9cd06ac5235a779726618e530d
LOCAL_EDGE_IMAGE=docker.io/library/caddy@sha256:4c6e91c6ed0e2fa03efd5b44747b625fec79bc9cd06ac5235a779726618e530d
ESIGNET_REDIS_IMAGE=redis@sha256:b99ffd0554dc8d300230b9d1b9f2a129a6abf595bf8589883beb980ed1feae3d
ESIGNET_BASE_IMAGE=mosipid/esignet-with-plugins@sha256:47fffdb5a45198b29885a533841129877a7385a12bcb6020c0f6d4335477be39
ESIGNET_UI_IMAGE=mosipid/oidc-ui@sha256:8a2a6839b4e22be6c967dabc6308190c165c54604a778c2d9b1aae8091db93e7
Expand Down
Loading