Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d0558d11b | ||
|
|
bfeee80712 |
@@ -13,26 +13,26 @@ authorization system and the key-document schema; the crypto primitives live in
|
||||
## Install
|
||||
|
||||
```
|
||||
envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v0.1.2
|
||||
envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v0.1.4
|
||||
```
|
||||
|
||||
Direct:
|
||||
|
||||
```bash
|
||||
pip install "envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v0.1.2"
|
||||
pip install "envelope_authorizer @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v0.1.4"
|
||||
```
|
||||
|
||||
The base install uses a local JSON file for storage (stdlib only). For shared
|
||||
dev→server storage, install the mongo extra:
|
||||
|
||||
```bash
|
||||
pip install "envelope_authorizer[mongo] @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v0.1.2"
|
||||
pip install "envelope_authorizer[mongo] @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_authorizer.git@v0.1.4"
|
||||
```
|
||||
|
||||
Installing pulls `envelope_crypto` (and `mongo` with the extra). After install,
|
||||
the `authorizer` command is on your PATH; `python -m envelope_authorizer` also works.
|
||||
|
||||
Drop the `@v0.1.2` suffix from the line above to install the latest unpinned.
|
||||
Drop the `@v0.1.4` suffix from the line above to install the latest unpinned.
|
||||
|
||||
## Trust model (read this)
|
||||
|
||||
@@ -129,7 +129,11 @@ initialized or the friendly name is taken.
|
||||
Boots the local DEK, verifies the local key is itself an authorizer, then wraps
|
||||
the same DEK to the target public key and stores a new key doc. Omit
|
||||
`--can-authorize` for servers (`allowed: False`); pass it only for trusted
|
||||
dev/home machines.
|
||||
dev/home machines. Refuses a target key whose fingerprint already has a record
|
||||
(most importantly the local key itself) — `save` upserts by `_id`, so
|
||||
authorizing an already-known key would silently replace its existing doc
|
||||
(capability flag and friendly name) under a success banner instead of adding a
|
||||
new key. Revoke the existing record first if you intend to re-authorize it.
|
||||
|
||||
```
|
||||
[✔] Authorized Jy7k2ey7... | friendly: server1 [can_authorize=False]
|
||||
|
||||
+2
-2
@@ -4,11 +4,11 @@ build-backend = "hatchling.build"
|
||||
|
||||
[project]
|
||||
name = "envelope_authorizer"
|
||||
version = "0.1.2"
|
||||
version = "0.1.4"
|
||||
description = "CLI key-authorization manager for envelope_crypto"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"envelope_crypto @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_crypto.git@v0.1.0",
|
||||
"envelope_crypto @ git+ssh://git@git.rethinkstudios.io/rethink-public/envelope_crypto.git",
|
||||
"tomli>=2.0; python_version<'3.11'",
|
||||
]
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
__version__ = "0.1.2"
|
||||
__version__ = "0.1.4"
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
boots the local DEK, verifies the local key is itself an authorizer, then wraps
|
||||
the same DEK to the target public key and stores a new key doc. `--can-authorize`
|
||||
decides whether the new key may authorize others (omit it for servers).
|
||||
decides whether the new key may authorize others (omit it for servers). Refuses
|
||||
a target key that fingerprints to an existing `_id` — `save` upserts by `_id`, so
|
||||
authorizing a key that is already on record (most dangerously the local key
|
||||
itself) would silently replace that doc's capability flag and friendly name
|
||||
under a success banner instead of adding a new key.
|
||||
"""
|
||||
|
||||
from . import (
|
||||
@@ -10,6 +14,7 @@ from . import (
|
||||
boot_local,
|
||||
build_doc,
|
||||
find_by_friendly,
|
||||
local_fingerprint,
|
||||
make_flag,
|
||||
read_flag,
|
||||
)
|
||||
@@ -25,9 +30,23 @@ def run(config, storage, args) -> None:
|
||||
if not read_flag(crypto, local_doc["meta"]["authorizer"]):
|
||||
raise CommandError("this key is not permitted to authorize others")
|
||||
|
||||
new_fp, new_wrapped = crypto.encrypt_aes_key_with_rsa(
|
||||
crypto.master_key, args.key
|
||||
)
|
||||
new_fp = crypto.get_rsa_key_fingerprint(args.key)
|
||||
if new_fp == local_fingerprint(crypto, config):
|
||||
raise CommandError(
|
||||
"target key is the local key; authorize would silently replace the "
|
||||
"local authorizer record — use a different keypair, or `authorizer "
|
||||
"list` if you meant to check its status"
|
||||
)
|
||||
existing = storage.get(new_fp)
|
||||
if existing:
|
||||
existing_friendly = existing.get("meta", {}).get("friendly", "?")
|
||||
raise CommandError(
|
||||
f"target key is already authorized as '{existing_friendly}'; "
|
||||
f"authorize would silently replace that record — revoke it first "
|
||||
f"if you intend to re-authorize it"
|
||||
)
|
||||
|
||||
_, new_wrapped = crypto.encrypt_aes_key_with_rsa(crypto.master_key, args.key)
|
||||
flag = make_flag(crypto, args.can_authorize)
|
||||
doc = build_doc(new_fp, new_wrapped, flag, config.identity, args.friendly)
|
||||
storage.save(doc)
|
||||
|
||||
Reference in New Issue
Block a user