owned this note
owned this note
Published
Linked with GitHub
# Super-simple TUF metadata CRUD API
## Create
### Key manipulation
Something like [this](https://github.com/cnabio/signy/blob/master/scripts/in-toto/keys.py) has proven to be useful in practice, at least for one author.
### Single-file metadata manipulation
```python
# something generic to mng keys, don't make me think about it
key_mgr = securesystemslib.something(
backend=oneOf('kms', 'filesystem')
)
tuf.create_repository(
'name',
storage_backend=...,
# just high-level info like keys and expirations
root=...,
timestamp=...,
snapshot=...
targets=...,
)
# no effect is repo.lazy_writes=True
repo.flush()
repo = tuf.load_repository(
'name',
storage_backend=...
)
# add initial targets
repo.metadata.targets.add_target(
'filename',
# optional, can include custom
fileinfo=...
)
# delegated targets
repo.metadata.targets.delegate(
name='bins',
pattern="*",
keys=[],
threshold=...,
terminating=True,
)
repo.metadata.targets['bins'].add_target(...)
# XXXX-XXXX
# repo.metadata.targets['bins']['bin-0']
repo.metadata.targets['bins'].delegate_bins(
count=1024,
# range(count)
prefix='bin-',
# assumption is we will reuse these for all bins
keys=[],
threshold=...,
terminating=True,
)
repo.metadata.targets['bins'].add_target(
...,
binned=True
)
# no effect is repo.lazy_writes=True
repo.flush()
```
## Read
```python
# fetches ONLY top-level metadata
repo = tuf.load_repository(
'name',
storage_backend=...
)
# just use the accessors, like so
# suppose A delegated to B and B delegated to D
# and A delegated to C and C delegated to D
# no problem, you get different delegation keys by simply walking through the different paths in the diamond
repo.metadata.targets['a']['b']['d']
repo.metadata.targets['a']['c']['d']
# iterates over all targets in the targets dir, not by walking thru metadata
print(str(len(repo.targets)))
```
## Update
### Add target to bin
```python
# fetches ONLY top-level metadata
repo = tuf.load_repository(
'name',
storage_backend=...
)
# Lazy read, but aggressive write
# Timestamp and snapshot should automagically update
repo.targets['bins'].add_target(
'filename',
fileinfo=...,
binned=True
)
# no effect is repo.lazy_writes=True
repo.flush()
```
### Bump version number and expiration for any role
```python
# human-readable deltas pls
repo.bump_role(tuf.TIMESTAMP, delta='1d')
```
### Key manipulation
How you use the key should be completely agnostic to TUF. In fact, it shouldn't even bother loading keys, because they could be on a HSM. At the very least, need a super-simple API to simply attach signatures.
Don't make me think about key IDs and all that stuff.
```python
class KeyRing:
def __init__(self, threshold, keys, ...): pass
...
class Key:
def sign(self, data): pass
def verify(self, data): pass
```
Questions:
1. How to handle missing keys, leading to going under threshold of signatures?
2. When to verify signatures?
## Delete