From eced5333d6845d4002d232564a274c575aae3859 Mon Sep 17 00:00:00 2001 From: disqualifier Date: Mon, 29 Jun 2026 01:10:25 -0400 Subject: [PATCH] fix: surface a tampered capability flag as a clean error, not a traceback MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit a tampered or foreign GCM capability flag raises cryptography's InvalidTag (subclasses Exception, not ValueError/RuntimeError), which escaped the CLI's catch tuple as a raw traceback on the authorize/verify paths. main() now catches InvalidTag and surfaces '[\xe2\x9c\x98] capability flag failed authentication — tampered or wrong DEK'. also corrected the stale CLAUDE.md storage note that still described the swallow-wrapped mongo methods instead of the fail-loud raw-collection path. Signed-off-by: disqualifier --- src/envelope_authorizer/cli.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/envelope_authorizer/cli.py b/src/envelope_authorizer/cli.py index 047d4ad..6a0ae17 100644 --- a/src/envelope_authorizer/cli.py +++ b/src/envelope_authorizer/cli.py @@ -9,6 +9,8 @@ command loads config and resolves a storage backend first. expected failures import argparse import sys +from cryptography.exceptions import InvalidTag + from . import __version__ from .config import ConfigError, load_config from .commands import CommandError, authorize, config_init, init, list_keys, revoke, verify @@ -88,6 +90,8 @@ def main() -> int: storage = resolve(config) handlers[args.cmd](config, storage, args) return 0 + except InvalidTag: + return _fail("capability flag failed authentication — tampered or wrong DEK") except (ConfigError, CommandError, RuntimeError, ValueError, FileNotFoundError) as error: return _fail(str(error))