Bootstrap Key Generation
Overview
This document describes the implementation details of the bootstrap key generation functionality for TUF (The Update Framework) in the faynoSync system. The bootstrap process allows you to initialize a TUF repository with the necessary cryptographic keys and metadata.
API Endpoint
POST /tuf/v1/bootstrap/generate
Method: POST
Path: /tuf/v1/bootstrap/generate
Authentication: Required (via authMiddleware)
Permissions: Administrators only (via adminMiddleware)
This endpoint is registered in the SetupRoutes function in the bootstrap.go file and is only available to users with administrator privileges.
Architecture and Concept
Generation for a Specific Administrator
It is important to understand that key generation is performed not for the entire server, but for a specific administrator. This means:
- Each administrator has their own set of TUF keys
- Private keys are stored in MongoDB with a binding to
adminName - Keys are stored in the
tuf_private_keyscollection with theadmin_namefield - When regenerating, old administrator keys are deleted before saving new ones
Generation Process
The generateRootKeys function performs the following steps:
- Obtain administrator name from the request context
- Create TUF roles and metadata
- Generate cryptographic keys for each role
- Sign metadata with generated keys
- Save metadata to temporary directory
- Save private keys in MongoDB
- Generate bootstrap payload from metadata
- Return payload in response
Detailed Process Description
1. Creating TUF Roles and Metadata
root := metadata.Root(tuf_utils.HelperExpireIn(365))
roles.SetRoot(root)
The system creates four main TUF roles:
- targets - expiration 7 days
- snapshot - expiration 7 days
- timestamp - expiration 1 day
- root - expiration 365 days
Each role has its own metadata with the corresponding expiration period.
2. Key Generation
For each role, the following is generated:
- Private key of type
ed25519(cryptography standard for TUF) - Public key extracted from the private key
- Key ID calculated automatically and stored for future use
3. Additional Root Key
The system generates an additional root key for enhanced security:
- Root role has threshold = 2, meaning two signatures are required for changes to root metadata
- Both root keys are stored separately (
rootandroot_extra)
4. Signing Metadata
Each metadata is signed with the corresponding private key of its role.
5. Saving Metadata to Files
A temporary directory is created (e.g., tmp1234567890) in the current working directory, where the following are stored:
1.root.json- root metadata (version 1)1.targets.json- targets metadata (version 1)1.snapshot.json- snapshot metadata (version 1)timestamp.json- timestamp metadata (without version)
6. Additional Root Metadata Signing
Root metadata is signed with the second root key to achieve threshold = 2, then validated.
7. Saving Private Keys in MongoDB
Private keys are stored in the tuf_private_keys collection with the following structure:
admin_name- administrator namerole_name- role name ("root", "targets", "snapshot", "timestamp", "root_extra")key_id- public key IDprivate_key- private key in Base64 formatkey_type- key type ("ed25519")created_at/updated_at- timestamps
Important: Before saving new keys, all old keys for this administrator are deleted.
8. Generating Bootstrap Payload
The generatePayload function reads the generated metadata and creates a structured payload with:
- Expiration settings for each role
- Root metadata
- Bins settings (if needed)
- Timeout value
Response Structure
Successful Response (HTTP 200)
{
"data": {
"settings": {
"roles": {
"root": {
"expiration": 365
},
"timestamp": {
"expiration": 1
},
"snapshot": {
"expiration": 7
},
"targets": {
"expiration": 365
},
"bins": {
"expiration": 1,
"number_of_delegated_bins": 4
}
}
},
"metadata": {
"root": {
"signatures": [
{
"keyid": "9f010db5ae2803cd78dc0b3cb63447b322bf708ed15922a9b6e017f2fde61432",
"sig": "5b410d8b54cb9e0fe9c3f74eb13376dc7df32eccf77939e1c9179fe8fa127fb994e36e860d9418fd2e5cace5ad7da9bb31b568b76fdcacbec0d34b0ac4e6be03"
},
{
"keyid": "ebbfdeb46956d0c58eaa5f5220b9d69168481d17ceac0c2f769168455f85acd0",
"sig": "ef4c156e39159fb710dcd5a6ffc9d953934a389fb3accdb13dc96491a79e7ce48c2fcc79790ea012397b221f36c264d1d07b95aa2facdb2b0af2acb182590b01"
}
],
"signed": {
"_type": "root",
"version": 1,
"spec_version": "1.0.0",
"expires": "2026-11-27T12:01:12.80776Z",
"consistent_snapshot": true,
"keys": {
"16a650c3c7fc796c698395bff55e24e04c71222dda0c9ca1e956c7e28ad56507": {
"keytype": "ed25519",
"scheme": "ed25519",
"keyval": {
"public": "fa0ecc9429c2bceefdcefc433c3396e396f3bdbd594856fbcd1017da32402722"
}
}
},
"roles": {
"root": {
"keyids": ["9f010db5ae2803cd78dc0b3cb63447b322bf708ed15922a9b6e017f2fde61432", "ebbfdeb46956d0c58eaa5f5220b9d69168481d17ceac0c2f769168455f85acd0"],
"threshold": 2
},
"targets": {
"keyids": ["..."],
"threshold": 1
},
"snapshot": {
"keyids": ["..."],
"threshold": 1
},
"timestamp": {
"keyids": ["..."],
"threshold": 1
}
}
}
}
},
"timeout": 300
},
"message": "Root keys generated and payload created successfully"
}
Errors
401 Unauthorized - if the user is not authenticated or is not an administrator:
{
"error": "Unauthorized"
}
500 Internal Server Error - if failed to save keys:
{
"error": "Failed to save private keys to database"
}
500 Internal Server Error - if failed to generate payload:
{
"error": "Failed to generate bootstrap payload"
}
Generated Files
During function execution, the following files are created in a temporary directory:
Location
A temporary directory is created in the current working directory of the server with the prefix tmp and a random numeric suffix (e.g., tmp1212824492).
Metadata Files
-
1.root.json- Root metadata version 1- Contains public keys of all roles
- Contains role settings (threshold, keyids)
- Signed by two root keys (threshold = 2)
- Expiration: 365 days
-
1.targets.json- Targets metadata version 1- Contains information about target files
- Signed by targets key
- Expiration: 7 days (by default)
-
1.snapshot.json- Snapshot metadata version 1- Contains information about versions of other metadata
- Signed by snapshot key
- Expiration: 7 days (by default)
-
timestamp.json- Timestamp metadata- Contains the latest information about snapshot
- Signed by timestamp key
- Expiration: 1 day (by default)
- Does not have a version in the filename
Note: These files are stored only temporarily for payload generation. After returning the response, they remain in the file system (may be deleted later by the system or manually).
Security and Features
Key Isolation Between Administrators
- Each administrator has their own set of keys
- Keys are stored with a binding to
admin_name - When regenerating, old keys are deleted
Threshold for Root Role
- Root role has threshold = 2, requiring two signatures for changes
- This enhances security for critical operations with root metadata
Key Type
- Only
ed25519is used - a modern and secure algorithm - Private keys are stored in Base64 format
Validation
- After generation, root metadata is validated via
tuf_metadata.ValidateRoot() - This ensures correctness of structure and signatures
Usage
After successful generation, the bootstrap payload can be used for:
- Initializing the TUF repository via the
POST /tuf/v1/bootstrapendpoint - Saving role expiration settings
- Configuring the update system through the TUF protocol
The payload contains all necessary information for complete TUF repository initialization for a specific administrator.