tuf: Support importing root keys from a fioctl tarball#199
Merged
Conversation
vkhoroz
reviewed
Jul 8, 2026
51b9d44 to
4606e14
Compare
Member
Author
|
This has been tested e2e migrating a foundries factory device to my update server instance with the help of fioctl pr foundriesio/fioctl#541 |
vkhoroz
reviewed
Jul 12, 2026
vkhoroz
left a comment
Member
There was a problem hiding this comment.
This looks good to me.
I'm only a bit surprised by a sheer amount of code needed to do this.
But that's irrelevant. You did a great job.
Add an optional --import-keys flag to the tuf-init command that reads a fioctl/ota-tuf tarball containing the offline root key(s) and root.json. The imported root.json files are stored verbatim, fresh online keys are generated for every role, and a new root.json is created and signed by both the imported (old) root key(s) and the new root key so clients can verify the chain of trust. Fixes bug #189 Signed-off-by: Andy Doan <doanac@qti.qualcomm.com> Co-authored-by: GitHub Copilot <bot@github.com>
vkhoroz
approved these changes
Jul 13, 2026
vkhoroz
left a comment
Member
There was a problem hiding this comment.
LGTM
I'd still recommend to sort out that feeling of adding multiple old key signatures.
(That what the code seems to do, but we only ever have one matching old key in the tarball).
Feel free to merge when you like it.
Comment on lines
+72
to
+85
| fmt.Println() | ||
| fmt.Println("TUF initialization completed successfully.") | ||
| fmt.Println() | ||
| fmt.Println("IMPORTANT: A new root key was created at:") | ||
| fmt.Printf(" %s\n", rootKeyPath) | ||
| fmt.Println() | ||
| fmt.Println("This key is encrypted at rest using the HMAC secret at:") | ||
| fmt.Printf(" %s\n", hmacPath) | ||
| fmt.Println() | ||
| fmt.Println("Make a backup copy of BOTH files and store them somewhere safe NOW.") | ||
| fmt.Println("The root key is useless without the HMAC secret needed to decrypt it.") | ||
| fmt.Println("If either file is lost it CANNOT be recovered, and you will permanently") | ||
| fmt.Println("lose the ability to rotate or manage your TUF root of trust.") | ||
| fmt.Println() |
Member
There was a problem hiding this comment.
Maybe, use a multi-line format, like this:
Suggested change
| fmt.Println() | |
| fmt.Println("TUF initialization completed successfully.") | |
| fmt.Println() | |
| fmt.Println("IMPORTANT: A new root key was created at:") | |
| fmt.Printf(" %s\n", rootKeyPath) | |
| fmt.Println() | |
| fmt.Println("This key is encrypted at rest using the HMAC secret at:") | |
| fmt.Printf(" %s\n", hmacPath) | |
| fmt.Println() | |
| fmt.Println("Make a backup copy of BOTH files and store them somewhere safe NOW.") | |
| fmt.Println("The root key is useless without the HMAC secret needed to decrypt it.") | |
| fmt.Println("If either file is lost it CANNOT be recovered, and you will permanently") | |
| fmt.Println("lose the ability to rotate or manage your TUF root of trust.") | |
| fmt.Println() | |
| fmt.Printf(` | |
| TUF initialization completed successfully. | |
| IMPORTANT: A new root key was created at: | |
| %s | |
| This key is encrypted at rest using the HMAC secret at: | |
| %s | |
| Make a backup copy of BOTH files and store them somewhere safe NOW. | |
| The root key is useless without the HMAC secret needed to decrypt it. | |
| If either file is lost it CANNOT be recovered, and you will permanently | |
| lose the ability to rotate or manage your TUF root of trust. | |
| `, | |
| rootKeyPath, hmacPath) |
On successful tuf-init (both fresh init and root import), print a notice that a new root key was created and must be backed up along with the hmac.secret used to encrypt it at rest. The root key is unrecoverable if lost. Document the same guidance in the quick-start guide. Signed-off-by: Andy Doan <doanac@qti.qualcomm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add an optional --import-keys flag to the tuf-init command that reads a fioctl/ota-tuf tarball containing the offline root key(s) and root.json. The imported root.json files are stored verbatim, fresh online keys are generated for every role, and a new root.json is created and signed by both the imported (old) root key(s) and the new root key so clients can verify the chain of trust.
Chatting with Copilot on this, it was decided to be more efficient to use our own code for talking with the FIO backend for getting the root.json files rather than trying to integrate with the fioctl client library code.
Fixes bug #189