Compare commits

...
2 Commits
Author SHA1 Message Date
zemion c42a7816fd Define governed secure mail profiles 2026-08-04 14:02:21 +02:00
zemion a63d541f0e Harden module package publication 2026-08-04 14:02:10 +02:00
3 changed files with 29 additions and 22 deletions
+4 -21
View File
@@ -14,6 +14,8 @@ on:
jobs:
publish-packages:
runs-on: ubuntu-latest
env:
GITEA_REPOSITORY: ${{ gitea.repository }}
steps:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
@@ -29,7 +31,6 @@ jobs:
env:
REQUESTED_TAG: ${{ inputs.release_tag }}
TRIGGER_TAG: ${{ gitea.ref_name }}
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
tag="${REQUESTED_TAG:-$TRIGGER_TAG}"
@@ -43,24 +44,6 @@ jobs:
echo "Release tag is not contained in main" >&2
exit 1
}
python - "$tag" <<'PY'
import fnmatch
import json
import os
import sys
import urllib.request
tag = sys.argv[1]
repository = os.environ["GITEA_REPOSITORY"]
request = urllib.request.Request(
f"{os.environ['GITEA_API_URL']}/repos/{repository}/tag_protections",
headers={"Authorization": f"token {os.environ['GITEA_TOKEN']}"},
)
with urllib.request.urlopen(request, timeout=30) as response:
protections = json.load(response)
if not any(fnmatch.fnmatchcase(tag, item.get("name_pattern", "")) for item in protections):
raise SystemExit(f"Release tag {tag!r} is not covered by repository tag protection")
PY
git checkout --detach "$tag"
printf 'RELEASE_TAG=%s\n' "$tag" >> "$GITEA_ENV"
printf 'SOURCE_DATE_EPOCH=%s\n' "$(git show -s --format=%ct HEAD)" >> "$GITEA_ENV"
@@ -130,7 +113,7 @@ jobs:
const escapedRepository = repository.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const gitTag = specifier.match(
new RegExp(
`^git\\+(?:ssh://git@|https://)git\\.add-ideas\\.de/GovOPlaN/${escapedRepository}\\.git#v([0-9]+\\.[0-9]+\\.[0-9]+)$`,
`^git\\+(?:ssh://git@|https://)git\\.add-ideas\\.de/(?:GovOPlaN|add-ideas)/${escapedRepository}\\.git#v([0-9]+\\.[0-9]+\\.[0-9]+)$`,
),
);
if (gitTag) {
@@ -203,7 +186,7 @@ jobs:
'@govoplan:registry=https://git.add-ideas.de/api/packages/GovOPlaN/npm/' \
"//git.add-ideas.de/api/packages/GovOPlaN/npm/:_authToken=$PACKAGE_TOKEN" \
> "$npmrc"
NPM_CONFIG_USERCONFIG="$npmrc" npm publish "${webui_packages[0]}" \
NPM_CONFIG_USERCONFIG="$npmrc" npm publish "./${webui_packages[0]}" \
--ignore-scripts --access public \
--registry https://git.add-ideas.de/api/packages/GovOPlaN/npm/
fi
+3 -1
View File
@@ -125,7 +125,9 @@ does not contribute these routes directly.
POP3 and JMAP are deferred. The protocol decision is documented in
[docs/MAIL_PROTOCOL_ROADMAP.md](docs/MAIL_PROTOCOL_ROADMAP.md): stabilize
SMTP/IMAP first, prefer JMAP for modern mailbox sync/search later, and add POP3
only for explicit legacy-download requirements.
only for explicit legacy-download requirements. The same roadmap records the
approved S/MIME-first, OpenPGP-additional message-protection profile and its
no-silent-downgrade requirement.
Platform RBAC and governance rules are documented in `govoplan-core/docs/`.
The [Mail handbook](docs/MAIL_HANDBOOK.md) provides the adaptive user,
+22
View File
@@ -13,6 +13,28 @@ and JMAP are deferred until the IMAP mailbox MVP is stable.
This baseline matches the first production use case: send campaign mail, append
sent copies when configured, and inspect mailboxes read-only.
## Message Protection Profiles
The product and security profile approved on 2026-08-04 makes S/MIME the first
institutional signing/encryption profile and OpenPGP an additional explicit
profile. Neither profile is implemented by treating protection as a local Mail
toggle:
- private-key custody belongs to an Encryption/KMS provider and usable private
keys are never persisted by Mail;
- recipient certificates and keys initially come from administered directory
or LDAP sources; opportunistic Internet discovery is deferred;
- required signing or encryption fails closed when material is missing,
expired, revoked, unverifiable, or its provider is unavailable;
- plaintext fallback is permitted only by an explicit, audited policy and is
never inferred from provider failure; and
- delivery evidence pins the signing identity, trust/revocation evidence,
algorithm suite, key version, and any explicit downgrade decision.
Provider-neutral S/MIME custody and interoperability fixtures are the first
implementation slice. OpenPGP uses the same no-silent-downgrade boundary after
the S/MIME profile is stable.
## JMAP
JMAP is the preferred future sync/search protocol where target mail servers