From 28f45457746ee3674d45bd23f5d836ece3bde728 Mon Sep 17 00:00:00 2001 From: Kaan Yagci Date: Sat, 5 Sep 2026 09:33:30 +0200 Subject: [PATCH 1/5] feat(security): add Brio runtime observer --- scripts/brio-runtime-observe.sh | 78 ++++++++++++++++++++++++ scripts/install-brio-runtime-observer.sh | 53 ++++++++++++++++ scripts/run-ci.sh | 4 ++ scripts/test-brio-runtime-observer.sh | 41 +++++++++++++ 4 files changed, 176 insertions(+) create mode 100755 scripts/brio-runtime-observe.sh create mode 100755 scripts/install-brio-runtime-observer.sh create mode 100755 scripts/test-brio-runtime-observer.sh diff --git a/scripts/brio-runtime-observe.sh b/scripts/brio-runtime-observe.sh new file mode 100755 index 0000000..4455276 --- /dev/null +++ b/scripts/brio-runtime-observe.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +export PATH=/usr/bin:/bin +umask 077 + +readonly expected_command=shared-runtime-observe +readonly expected_container=postgres-postgres-1 +readonly expected_project=postgres +readonly expected_service=postgres +readonly image_pattern='^postgres:16-alpine@sha256:[a-f0-9]{64}$' +readonly image_id_pattern='^sha256:[a-f0-9]{64}$' + +die() { + printf '%s\n' "$1" >&2 + exit 1 +} + +docker_short() { + timeout --signal=KILL 20s docker "$@" +} + +(( EUID == 0 )) || die 'The Brio PostgreSQL runtime observer must run through its exact passwordless sudo rule.' +[[ "${SSH_ORIGINAL_COMMAND:-}" == "${expected_command}" ]] || \ + die 'The Brio PostgreSQL runtime observer accepts only shared-runtime-observe.' + +record=$(docker_short inspect --type container --format \ + '{{.Id}}|{{.Name}}|{{.Config.Image}}|{{.Image}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}|{{.State.StartedAt}}|{{.RestartCount}}|{{index .Config.Labels "com.docker.compose.project"}}|{{index .Config.Labels "com.docker.compose.service"}}|{{index .Config.Labels "com.docker.compose.oneoff"}}|{{.HostConfig.NetworkMode}}' \ + "${expected_container}") || die 'Cannot inspect the shared PostgreSQL container.' +IFS='|' read -r container_id container_name image runtime_image_id state health started_at restart_count \ + compose_project compose_service compose_oneoff network_mode <<< "${record}" + +[[ "${container_id}" =~ ^[a-f0-9]{64}$ && "${container_name}" == "/${expected_container}" ]] || \ + die 'Shared PostgreSQL returned an invalid container identity.' +[[ "${image}" =~ ${image_pattern} && "${runtime_image_id}" =~ ${image_id_pattern} ]] || \ + die 'Shared PostgreSQL is not running an immutable reviewed image reference.' +[[ "${state}" == running && "${health}" == healthy ]] || die 'Shared PostgreSQL is not running and healthy.' +[[ "${compose_project}" == "${expected_project}" && "${compose_service}" == "${expected_service}" \ + && "${compose_oneoff}" == False && "${network_mode}" == host ]] || \ + die 'Shared PostgreSQL has unexpected Compose identity or network mode.' +[[ "${started_at}" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.+-]+Z$ && "${restart_count}" =~ ^[0-9]+$ ]] || \ + die 'Shared PostgreSQL returned invalid lifecycle identity.' + +resolved_image_id=$(docker_short image inspect "${image}" --format '{{.Id}}') || \ + die 'Cannot resolve the shared PostgreSQL immutable image reference.' +[[ "${resolved_image_id}" == "${runtime_image_id}" ]] || \ + die 'Shared PostgreSQL container content does not match its immutable image reference.' +version_output=$(docker_short exec "${container_id}" postgres --version 2>&1) || \ + die 'Cannot read the running PostgreSQL version.' +[[ "${version_output}" =~ ^postgres\ \(PostgreSQL\)\ (16\.[0-9]+)(\.[0-9]+)?$ ]] || \ + die 'Shared PostgreSQL returned an unexpected runtime version.' +version=${BASH_REMATCH[1]}${BASH_REMATCH[2]:-} + +python3 - "${image}" "${runtime_image_id}" "${version}" "${container_id}" \ + "${started_at}" "${restart_count}" <<'PY' +import json +import sys + +image, image_id, version, container_id, started_at, restart_count = sys.argv[1:] +payload = { + "schema": "makepad.brio.runtime-host-observation.v1", + "hostRole": "database", + "components": [{ + "name": "postgres", + "orchestrator": "compose", + "unit": "postgres/postgres", + "image": image, + "runtimeImageID": image_id, + "version": version, + "state": "running", + "health": "healthy", + "instanceID": f"sha256:{container_id}", + "startedAt": started_at, + "restartCount": int(restart_count), + }], +} +print(json.dumps(payload, sort_keys=True, separators=(",", ":"))) +PY diff --git a/scripts/install-brio-runtime-observer.sh b/scripts/install-brio-runtime-observer.sh new file mode 100755 index 0000000..f7ccd14 --- /dev/null +++ b/scripts/install-brio-runtime-observer.sh @@ -0,0 +1,53 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +readonly observer_user=brio-runtime-observer +readonly observer_home=/var/lib/brio-runtime-observer +readonly observer_command=/usr/local/libexec/makepad/brio-postgres-runtime-observe +readonly sudoers_path=/etc/sudoers.d/brio-postgres-runtime-observer + +die() { + printf '%s\n' "$1" >&2 + exit 1 +} + +(( EUID == 0 )) || die 'Run this installer as root on the PostgreSQL host.' +[[ $# == 2 ]] || die 'usage: install-brio-runtime-observer.sh OBSERVER_SCRIPT ED25519_PUBLIC_KEY_FILE' +source_script=$1 +public_key_file=$2 +[[ -f "${source_script}" && ! -L "${source_script}" ]] || die 'Observer source must be a regular file.' +[[ -f "${public_key_file}" && ! -L "${public_key_file}" ]] || die 'Observer public key must be a regular file.' + +read -r key_type key_body key_extra < "${public_key_file}" +[[ "${key_type}" == ssh-ed25519 && "${key_body}" =~ ^[A-Za-z0-9+/]+={0,3}$ && -z "${key_extra:-}" ]] || \ + die 'Expected exactly one OpenSSH Ed25519 public key without trailing fields.' +[[ $(wc -l < "${public_key_file}") -eq 1 ]] || die 'Observer public key file must contain exactly one line.' + +if ! id "${observer_user}" >/dev/null 2>&1; then + useradd --system --create-home --home-dir "${observer_home}" --shell /bin/bash "${observer_user}" +fi +[[ "$(id -u -n "${observer_user}")" == "${observer_user}" ]] || die 'Observer account could not be verified.' +passwd --lock "${observer_user}" >/dev/null + +install -d -o root -g root -m 0755 /usr/local/libexec /usr/local/libexec/makepad +install -o root -g root -m 0755 "${source_script}" "${observer_command}" +install -d -o "${observer_user}" -g "${observer_user}" -m 0700 "${observer_home}/.ssh" + +authorized_keys=$(mktemp) +sudoers_candidate=$(mktemp) +trap 'rm -f -- "${authorized_keys}" "${sudoers_candidate}"' EXIT +printf 'restrict,command="/usr/bin/sudo -n %s" %s %s\n' \ + "${observer_command}" "${key_type}" "${key_body}" > "${authorized_keys}" +install -o "${observer_user}" -g "${observer_user}" -m 0600 \ + "${authorized_keys}" "${observer_home}/.ssh/authorized_keys" + +printf 'Defaults!%s env_keep += "SSH_ORIGINAL_COMMAND"\n' "${observer_command}" > "${sudoers_candidate}" +printf '%s ALL=(root) NOPASSWD: %s\n' "${observer_user}" "${observer_command}" >> "${sudoers_candidate}" +chmod 0440 "${sudoers_candidate}" +visudo -cf "${sudoers_candidate}" >/dev/null +install -o root -g root -m 0440 "${sudoers_candidate}" "${sudoers_path}" + +[[ "$(stat -c '%U:%G:%a' "${observer_command}")" == root:root:755 ]] || die 'Observer command permissions are unsafe.' +[[ "$(stat -c '%U:%G:%a' "${sudoers_path}")" == root:root:440 ]] || die 'Observer sudo rule permissions are unsafe.' +[[ "$(stat -c '%U:%G:%a' "${observer_home}/.ssh/authorized_keys")" == \ + "${observer_user}:${observer_user}:600" ]] || die 'Observer authorized_keys permissions are unsafe.' diff --git a/scripts/run-ci.sh b/scripts/run-ci.sh index 96f251a..9c542a5 100755 --- a/scripts/run-ci.sh +++ b/scripts/run-ci.sh @@ -17,6 +17,8 @@ shellcheck \ scripts/install-keycloak-cohort-cleaner.sh \ scripts/keycloak-cohort-capture-dispatch.sh \ scripts/install-keycloak-cohort-capture-host.sh \ + scripts/brio-runtime-observe.sh \ + scripts/install-brio-runtime-observer.sh \ scripts/verify-brio-encrypted-restore.sh \ scripts/test-brio-bootstrap.sh \ scripts/test-brio-db-transaction.sh \ @@ -26,6 +28,7 @@ shellcheck \ scripts/test-brio-deployment-contracts.sh \ scripts/test-brio-deployment-failures.sh \ scripts/test-brio-release-evidence.sh \ + scripts/test-brio-runtime-observer.sh \ scripts/test-keycloak-cohort-evidence.sh \ scripts/test-keycloak-cohort-hardening.sh \ scripts/test-postgres-ci-jit-result.sh \ @@ -70,6 +73,7 @@ git diff --check ./scripts/test-brio-deployment-contracts.sh ./scripts/test-brio-deployment-failures.sh ./scripts/test-brio-release-evidence.sh +./scripts/test-brio-runtime-observer.sh ./scripts/test-keycloak-cohort-evidence.sh ./scripts/test-keycloak-cohort-hardening.sh ./scripts/test-brio-bootstrap.sh diff --git a/scripts/test-brio-runtime-observer.sh b/scripts/test-brio-runtime-observer.sh new file mode 100755 index 0000000..fd07231 --- /dev/null +++ b/scripts/test-brio-runtime-observer.sh @@ -0,0 +1,41 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) +observer=${repo_root}/scripts/brio-runtime-observe.sh +installer=${repo_root}/scripts/install-brio-runtime-observer.sh + +for path in "${observer}" "${installer}"; do + [[ -f "${path}" && ! -L "${path}" ]] || { echo "missing runtime observer artifact: ${path}" >&2; exit 1; } + bash -n "${path}" +done + +for marker in \ + 'export PATH=/usr/bin:/bin' \ + 'SSH_ORIGINAL_COMMAND:-' \ + 'shared-runtime-observe' \ + 'timeout --signal=KILL 20s docker' \ + 'readonly expected_container=postgres-postgres-1' \ + 'com.docker.compose.project' \ + 'com.docker.compose.service' \ + 'runtimeImageID' \ + 'postgres --version' \ + 'makepad.brio.runtime-host-observation.v1'; do + grep -Fq -- "${marker}" "${observer}" || { echo "observer is missing ${marker}" >&2; exit 1; } +done + +for forbidden in 'Config.Env' 'Mounts' 'docker logs'; do + ! grep -Fq -- "${forbidden}" "${observer}" || { echo "observer contains forbidden inspection: ${forbidden}" >&2; exit 1; } +done + +for marker in \ + 'readonly observer_user=brio-runtime-observer' \ + 'restrict,command="/usr/bin/sudo -n %s"' \ + 'env_keep += "SSH_ORIGINAL_COMMAND"' \ + 'NOPASSWD:' \ + 'visudo -cf' \ + 'passwd --lock'; do + grep -Fq -- "${marker}" "${installer}" || { echo "installer is missing ${marker}" >&2; exit 1; } +done + +echo 'Brio PostgreSQL runtime observer contract passed.' From d067415e602a8551f957df52a167e9fc2188553f Mon Sep 17 00:00:00 2001 From: Kaan Yagci Date: Sat, 5 Sep 2026 09:33:30 +0200 Subject: [PATCH 2/5] docs(security): document runtime observer setup --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index e6994e2..bfa22ec 100644 --- a/README.md +++ b/README.md @@ -824,6 +824,26 @@ Brio staging uses only its isolated encrypted overlay and certificate-matching a postgres://brio_staging_app:@makepad-postgres-brio-staging:5432/brio_staging?sslmode=verify-full&sslrootcert=/etc/brio/postgres/ca.crt ``` +Brio release evidence observes the shared database runtime without receiving a +database or deployment credential. After deriving the public half of Brio's +dedicated release-observer SSH key from its canonical Proton Pass item, install +the bounded host observer once as root: + +```sh +scripts/install-brio-runtime-observer.sh \ + scripts/brio-runtime-observe.sh \ + /secure/operator-path/brio-release-observer.pub +``` + +The installer creates a locked `brio-runtime-observer` account whose key is +bound with OpenSSH `restrict` to one root-owned command. The command accepts +only `shared-runtime-observe`; it verifies the exact healthy standalone +`postgres/postgres` Compose unit, binds the running image content to its +immutable reference, and returns bounded image, version, and lifecycle JSON. +It cannot read database data, container environment or mounts, run arbitrary +Docker commands, or mutate the host. Never install a deployment key for this +account or mirror the observer private key to this repository. + If production overrides `DEPLOY_VIF_DB_NAME` or `DEPLOY_VIF_DB_USER`, use those values in the connection URI. ## Validation @@ -838,6 +858,7 @@ Run the static deployment checks and the disposable PostgreSQL 16 bootstrap test ./scripts/test-brio-deploy-guards.sh ./scripts/test-brio-deployment-contracts.sh ./scripts/test-brio-deployment-failures.sh +./scripts/test-brio-runtime-observer.sh ``` Run the local static checks before opening a deployment PR: @@ -851,4 +872,5 @@ bash scripts/test-brio-encrypted-restore.sh bash scripts/test-brio-deploy-guards.sh bash scripts/test-brio-deployment-contracts.sh bash scripts/test-brio-deployment-failures.sh +bash scripts/test-brio-runtime-observer.sh ``` From bce329842187e0bc5a0a07a4d7fa8cd5762c12ab Mon Sep 17 00:00:00 2001 From: Kaan Yagci Date: Sat, 5 Sep 2026 09:37:29 +0200 Subject: [PATCH 3/5] feat(security): attest PostgreSQL configuration digest --- scripts/brio-runtime-observe.sh | 10 ++++++---- scripts/test-brio-runtime-observer.sh | 2 ++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/scripts/brio-runtime-observe.sh b/scripts/brio-runtime-observe.sh index 4455276..4fa700f 100755 --- a/scripts/brio-runtime-observe.sh +++ b/scripts/brio-runtime-observe.sh @@ -25,10 +25,10 @@ docker_short() { die 'The Brio PostgreSQL runtime observer accepts only shared-runtime-observe.' record=$(docker_short inspect --type container --format \ - '{{.Id}}|{{.Name}}|{{.Config.Image}}|{{.Image}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}|{{.State.StartedAt}}|{{.RestartCount}}|{{index .Config.Labels "com.docker.compose.project"}}|{{index .Config.Labels "com.docker.compose.service"}}|{{index .Config.Labels "com.docker.compose.oneoff"}}|{{.HostConfig.NetworkMode}}' \ + '{{.Id}}|{{.Name}}|{{.Config.Image}}|{{.Image}}|{{.State.Status}}|{{if .State.Health}}{{.State.Health.Status}}{{else}}missing{{end}}|{{.State.StartedAt}}|{{.RestartCount}}|{{index .Config.Labels "com.docker.compose.project"}}|{{index .Config.Labels "com.docker.compose.service"}}|{{index .Config.Labels "com.docker.compose.oneoff"}}|{{index .Config.Labels "com.docker.compose.config-hash"}}|{{.HostConfig.NetworkMode}}' \ "${expected_container}") || die 'Cannot inspect the shared PostgreSQL container.' IFS='|' read -r container_id container_name image runtime_image_id state health started_at restart_count \ - compose_project compose_service compose_oneoff network_mode <<< "${record}" + compose_project compose_service compose_oneoff config_hash network_mode <<< "${record}" [[ "${container_id}" =~ ^[a-f0-9]{64}$ && "${container_name}" == "/${expected_container}" ]] || \ die 'Shared PostgreSQL returned an invalid container identity.' @@ -38,6 +38,7 @@ IFS='|' read -r container_id container_name image runtime_image_id state health [[ "${compose_project}" == "${expected_project}" && "${compose_service}" == "${expected_service}" \ && "${compose_oneoff}" == False && "${network_mode}" == host ]] || \ die 'Shared PostgreSQL has unexpected Compose identity or network mode.' +[[ "${config_hash}" =~ ^[a-f0-9]{64}$ ]] || die 'Shared PostgreSQL has an invalid Compose configuration digest.' [[ "${started_at}" =~ ^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.+-]+Z$ && "${restart_count}" =~ ^[0-9]+$ ]] || \ die 'Shared PostgreSQL returned invalid lifecycle identity.' @@ -52,11 +53,11 @@ version_output=$(docker_short exec "${container_id}" postgres --version 2>&1) || version=${BASH_REMATCH[1]}${BASH_REMATCH[2]:-} python3 - "${image}" "${runtime_image_id}" "${version}" "${container_id}" \ - "${started_at}" "${restart_count}" <<'PY' + "${started_at}" "${restart_count}" "${config_hash}" <<'PY' import json import sys -image, image_id, version, container_id, started_at, restart_count = sys.argv[1:] +image, image_id, version, container_id, started_at, restart_count, config_hash = sys.argv[1:] payload = { "schema": "makepad.brio.runtime-host-observation.v1", "hostRole": "database", @@ -66,6 +67,7 @@ payload = { "unit": "postgres/postgres", "image": image, "runtimeImageID": image_id, + "configDigest": f"sha256:{config_hash}", "version": version, "state": "running", "health": "healthy", diff --git a/scripts/test-brio-runtime-observer.sh b/scripts/test-brio-runtime-observer.sh index fd07231..3f35402 100755 --- a/scripts/test-brio-runtime-observer.sh +++ b/scripts/test-brio-runtime-observer.sh @@ -18,6 +18,8 @@ for marker in \ 'readonly expected_container=postgres-postgres-1' \ 'com.docker.compose.project' \ 'com.docker.compose.service' \ + 'com.docker.compose.config-hash' \ + 'configDigest' \ 'runtimeImageID' \ 'postgres --version' \ 'makepad.brio.runtime-host-observation.v1'; do From 00d586453584c95a309bd2b8b7a279e02e4fe401 Mon Sep 17 00:00:00 2001 From: Kaan Yagci Date: Sat, 5 Sep 2026 09:47:39 +0200 Subject: [PATCH 4/5] fix(security): pin observed PostgreSQL image --- scripts/brio-runtime-observe.sh | 4 ++-- scripts/test-brio-runtime-observer.sh | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/brio-runtime-observe.sh b/scripts/brio-runtime-observe.sh index 4fa700f..8e16dff 100755 --- a/scripts/brio-runtime-observe.sh +++ b/scripts/brio-runtime-observe.sh @@ -8,7 +8,7 @@ readonly expected_command=shared-runtime-observe readonly expected_container=postgres-postgres-1 readonly expected_project=postgres readonly expected_service=postgres -readonly image_pattern='^postgres:16-alpine@sha256:[a-f0-9]{64}$' +readonly expected_image=postgres:16-alpine@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777 readonly image_id_pattern='^sha256:[a-f0-9]{64}$' die() { @@ -32,7 +32,7 @@ IFS='|' read -r container_id container_name image runtime_image_id state health [[ "${container_id}" =~ ^[a-f0-9]{64}$ && "${container_name}" == "/${expected_container}" ]] || \ die 'Shared PostgreSQL returned an invalid container identity.' -[[ "${image}" =~ ${image_pattern} && "${runtime_image_id}" =~ ${image_id_pattern} ]] || \ +[[ "${image}" == "${expected_image}" && "${runtime_image_id}" =~ ${image_id_pattern} ]] || \ die 'Shared PostgreSQL is not running an immutable reviewed image reference.' [[ "${state}" == running && "${health}" == healthy ]] || die 'Shared PostgreSQL is not running and healthy.' [[ "${compose_project}" == "${expected_project}" && "${compose_service}" == "${expected_service}" \ diff --git a/scripts/test-brio-runtime-observer.sh b/scripts/test-brio-runtime-observer.sh index 3f35402..e815278 100755 --- a/scripts/test-brio-runtime-observer.sh +++ b/scripts/test-brio-runtime-observer.sh @@ -16,6 +16,7 @@ for marker in \ 'shared-runtime-observe' \ 'timeout --signal=KILL 20s docker' \ 'readonly expected_container=postgres-postgres-1' \ + 'postgres:16-alpine@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777' \ 'com.docker.compose.project' \ 'com.docker.compose.service' \ 'com.docker.compose.config-hash' \ From eb8b9fdd3ca56abc759c6185994d60bba7793080 Mon Sep 17 00:00:00 2001 From: Kaan Yagci Date: Sat, 5 Sep 2026 09:51:25 +0200 Subject: [PATCH 5/5] fix(security): pin observed PostgreSQL version --- scripts/brio-runtime-observe.sh | 2 ++ scripts/test-brio-runtime-observer.sh | 1 + 2 files changed, 3 insertions(+) diff --git a/scripts/brio-runtime-observe.sh b/scripts/brio-runtime-observe.sh index 8e16dff..7c03751 100755 --- a/scripts/brio-runtime-observe.sh +++ b/scripts/brio-runtime-observe.sh @@ -9,6 +9,7 @@ readonly expected_container=postgres-postgres-1 readonly expected_project=postgres readonly expected_service=postgres readonly expected_image=postgres:16-alpine@sha256:57c72fd2a128e416c7fcc499958864df5301e940bca0a56f58fddf30ffc07777 +readonly expected_version=16.14 readonly image_id_pattern='^sha256:[a-f0-9]{64}$' die() { @@ -51,6 +52,7 @@ version_output=$(docker_short exec "${container_id}" postgres --version 2>&1) || [[ "${version_output}" =~ ^postgres\ \(PostgreSQL\)\ (16\.[0-9]+)(\.[0-9]+)?$ ]] || \ die 'Shared PostgreSQL returned an unexpected runtime version.' version=${BASH_REMATCH[1]}${BASH_REMATCH[2]:-} +[[ "${version}" == "${expected_version}" ]] || die 'Shared PostgreSQL is not running the reviewed 16.14 runtime.' python3 - "${image}" "${runtime_image_id}" "${version}" "${container_id}" \ "${started_at}" "${restart_count}" "${config_hash}" <<'PY' diff --git a/scripts/test-brio-runtime-observer.sh b/scripts/test-brio-runtime-observer.sh index e815278..d90cfcb 100755 --- a/scripts/test-brio-runtime-observer.sh +++ b/scripts/test-brio-runtime-observer.sh @@ -23,6 +23,7 @@ for marker in \ 'configDigest' \ 'runtimeImageID' \ 'postgres --version' \ + 'readonly expected_version=16.14' \ 'makepad.brio.runtime-host-observation.v1'; do grep -Fq -- "${marker}" "${observer}" || { echo "observer is missing ${marker}" >&2; exit 1; } done