6 Commits
Author SHA1 Message Date
dsql d1fedb7d8e release: 1.2.0
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-10-16 02:41:29 -04:00
dsql 3ca2764750 fix: warn on key-id mismatch in list; pin envelope_crypto v1.1.0, mongo v1.1.0
envelope_crypto 1.1.0 raises KeyMismatchError (a ValueError) instead of
InvalidTag for a flag sealed under another key, which fell into the silent
ValueError arm of _can_authorize and dropped the D5 warning. catch it first
and warn naming both key ids. the mongo extra pin moves to the current
release so it co-installs with consumers on mongo v1.1.0.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-10-16 02:41:29 -04:00
dsql 30a2b9b2a6 chore: bump to 1.1.0 (D5 logging fix)
Signed-off-by: disqualifier <dev@disqualifier.me>
2026-08-10 23:00:50 -04:00
dsql eb7a2a3d18 fix: log InvalidTag on capability-flag decrypt (D5)
narrow list_keys _can_authorize's bare except: (KeyError, TypeError,
ValueError) degrade to '?' silently (benign/malformed/foreign-shape flag),
but a cryptography InvalidTag now logs WARNING first. a GCM auth-tag failure
on an authz flag is either a foreign key this host can't decrypt or a tampered
authz record, and this layer can't distinguish them - the security signal must
stay observable rather than render identically to a routine '?'.

logs the friendly name (fallback: fingerprint) only - no blob, DEK, or
exception repr. a swallow that recovers must log (settled rule).

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-08-10 22:56:57 -04:00
dsql d11cefe3df build: use git+https for inter-lib deps (docker ssh limitation)
docker builds can't use git+ssh (no ssh key / agent in the build), so the inter-lib
dependency references move to git+https (repos are public, anonymous clone). pins are
unchanged in target; bump to 1.0.2 so the https dependency spec ships under a new tag.
README install lines intentionally keep the ssh form for local/dev use.

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-20 22:25:06 -04:00
dsql 1e6f3bc44f fix: pin inter-lib dependencies to their v1.0.0 tags
the v1.0.0 release still pinned pre-1.0.0 sibling tags, so a fresh install dragged in
stale transitive deps. update the pin(s) to the current v1.0.x release and bump this lib
to 1.0.1 so the corrected dependency chain ships under a new tag (v1.0.0 left intact).

Signed-off-by: disqualifier <dev@disqualifier.me>
2026-07-17 17:46:10 -04:00
3 changed files with 32 additions and 9 deletions

No files matched your search

+4 -4
View File
@@ -13,26 +13,26 @@ authorization system and the key-document schema; the crypto primitives live in
## Install ## Install
``` ```
envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v1.0.0 envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v1.2.0
``` ```
Direct: Direct:
```bash ```bash
pip install "envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v1.0.0" pip install "envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v1.2.0"
``` ```
The base install uses a local JSON file for storage (stdlib only). For shared The base install uses a local JSON file for storage (stdlib only). For shared
dev→server storage, install the mongo extra: dev→server storage, install the mongo extra:
```bash ```bash
pip install "envelope_authorizer[mongo] @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v1.0.0" pip install "envelope_authorizer[mongo] @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v1.2.0"
``` ```
Installing pulls `envelope_crypto` (and `mongo` with the extra). After install, Installing pulls `envelope_crypto` (and `mongo` with the extra). After install,
the `authorizer` command is on your PATH; `python -m envelope_authorizer` also works. the `authorizer` command is on your PATH; `python -m envelope_authorizer` also works.
Drop the `@v1.0.0` suffix from the line above to install the latest unpinned. Drop the `@v1.2.0` suffix from the line above to install the latest unpinned.
## Trust model (read this) ## Trust model (read this)
+3 -3
View File
@@ -4,18 +4,18 @@ build-backend = "hatchling.build"
[project] [project]
name = "envelope_authorizer" name = "envelope_authorizer"
version = "1.0.0" version = "1.2.0"
description = "CLI key-authorization manager for envelope_crypto" description = "CLI key-authorization manager for envelope_crypto"
requires-python = ">=3.10" requires-python = ">=3.10"
dependencies = [ dependencies = [
"envelope_crypto @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_crypto.git", "envelope_crypto @ git+https://git.rethinkstudios.io/rethink-public/envelope_crypto.git@v1.1.0",
"cryptography>=42.0", "cryptography>=42.0",
"tomli>=2.0; python_version<'3.11'", "tomli>=2.0; python_version<'3.11'",
] ]
[project.optional-dependencies] [project.optional-dependencies]
mongo = [ mongo = [
"mongo @ git+ssh://git@git.rethinkstudios.io/rethink-public/mongo.git@v0.1.0", "mongo @ git+https://git.rethinkstudios.io/rethink-public/mongo.git@v1.1.0",
] ]
[project.scripts] [project.scripts]
+25 -2
View File
@@ -5,16 +5,39 @@ CAN_AUTHORIZE (`?` if unreadable here). prints only fingerprint/metadata - never
the wrapped key or DEK. the wrapped key or DEK.
""" """
import logging
from datetime import datetime, timezone from datetime import datetime, timezone
from cryptography.exceptions import InvalidTag
from envelope_crypto import KeyMismatchError
from . import boot_local, doc_meta, read_flag from . import boot_local, doc_meta, read_flag
log = logging.getLogger(__name__)
def _can_authorize(crypto, doc) -> str: def _can_authorize(crypto, doc) -> str:
"""decrypted authority of a doc as Yes/No, or `?` if unreadable here""" """decrypted authority of a doc as Yes/No, or `?` if unreadable here
a malformed flag degrades to `?` silently. a flag that can't be read here is
logged first (WARNING) so the security signal stays visible rather than render
identically to a `?`: a kid mismatch means it was sealed under another key; a GCM
auth-tag failure (no kid, pre-1.1.0 flag) is a foreign key or a tampered record
and this layer can't tell them apart.
"""
try: try:
return "Yes" if read_flag(crypto, doc["meta"]["authorizer"]) else "No" return "Yes" if read_flag(crypto, doc["meta"]["authorizer"]) else "No"
except Exception: except KeyMismatchError as error:
friendly = doc_meta(doc).get("friendly", doc.get("_id", "?"))
log.warning(
"flag %s sealed under another key (key id %s, loaded %s)", friendly, error.blob_kid, error.key_kid,
)
return "?"
except (KeyError, TypeError, ValueError):
return "?"
except InvalidTag:
friendly = doc_meta(doc).get("friendly", doc.get("_id", "?"))
log.warning("auth-tag verification failed for flag %s - foreign key or tampered record", friendly)
return "?" return "?"