Skip to content

add support for hw keys certs and attestations#2622

Open
ubiratansoares wants to merge 6 commits into
mainfrom
u/yubikeys-schema
Open

add support for hw keys certs and attestations#2622
ubiratansoares wants to merge 6 commits into
mainfrom
u/yubikeys-schema

Conversation

@ubiratansoares

@ubiratansoares ubiratansoares commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Towards #2501. Context here.

This PR introduces a new hardware-keys folder and assumes a convention that each subfolder corresponds to attestation files and (f9) certificates derived from a single Yubikey.

There is a minimal TOML schema addition + validation to link a team member with these folders and files. We don't expose any information from these files through team API for now.

Documentation on how to generate these files to rollow on Forge.

In general we can expect

  • 1 intermediate certificate file + 2 attestations file per key
  • a few members involved with TUF, signing, etc with 2+ hardware keys to brign info in

That means a few dozens of files a few Kbs each stored at this repo, which sounds doable.

I added two for myself related to PIV 9a (auth) as an example of these files.

@ubiratansoares
ubiratansoares force-pushed the u/yubikeys-schema branch 2 times, most recently from 5a3166c to 4a5d445 Compare July 23, 2026 13:53
@github-actions

github-actions Bot commented Jul 23, 2026

Copy link
Copy Markdown
Dry-run check results

[WARN  rust_team::sync] sync-team is running in dry mode, no changes will be applied.
[INFO  rust_team::sync] synchronizing crates-io
[INFO  rust_team::sync] synchronizing github
[INFO  rust_team::sync] 💻 Repo Diffs:
    📝 Editing repo 'rust-lang/libz-sys':
      Environments:
        ❌ Delete: copilot

@ubiratansoares
ubiratansoares marked this pull request as ready for review July 24, 2026 07:12

@marcoieni marcoieni left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Some initial comments 👍

AI disclosure

I used GPT5.6-Sol with the codex harness to find 6/7 of these findings

Comment thread docs/toml-schema.md Outdated
last-name = "Doe" # Your last name or preferred surname
account-handle = "john.doe" # The handle to define a @rust-lang.org account (e.g. john.doe@rust-lang.org)

hardware-keys = ["key-id"]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is unrelated to [google-workspace] so we should move it at the top, right?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

@ubiratansoares ubiratansoares Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we don't want to have a new top-folder directory, we could have hardware-keys under people, which also makes it more clear that it's related to that 🤔

Wdyt?

The con I can think of:

  • people now has a subdirectory, which might break some scripts
  • the URL for retreaving hardware keys might be longer?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about this, and tbh I don't have a strong opinion. I think the top-level folder causes less harm.

Comment thread src/validate.rs Outdated
wrapper(data.people(), errors, |person, _| {
for key in person.hardware_keys() {
if !data.hardware_keys(key) {
dbg!(data);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a leftover or you want to have it here? It might be to spammy, right? 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here

Comment thread src/validate.rs
}
Ok(())
});
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we could also add the following validation: "Enforce that a key is only owned by exactly one person" to avoid duplicates and orphans

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this new check here

Comment thread src/data.rs

let hardware_keys_dir = directory.join("hardware-keys");
for entry in std::fs::read_dir(hardware_keys_dir)? {
let path = entry?.path();

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's validate that path is a directory. Do we also validate that the directory contains the files we expect? (and only those files?)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For now we don't validate the dir contents because I don't know about whether we should always expect the attestation files for both the 9a and 9c slots. For example, perhaps there is an agreement that only 9a attestation is required.

I can clarify with that with folks involved in TUF, but anyhow, my take would be introduce this additional validation as a follow-up. Let me know whether it makes sense to you!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added here

Comment thread src/data.rs

pub(crate) fn hardware_keys(&self, key_alias: &str) -> bool {
self.hardware_keys.contains(&key_alias.to_string())
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

given that this is the only operation we do, should we use a BTreeSet instead of a Vec? Also, maybe there's a way to check that the element is contained without allocating a string (to_string) ? 🤔

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added an equivalent check that don't allocate here

Comment thread src/schema.rs Outdated
#[serde(default)]
permissions: Permissions,
google_workspace: Option<GoogleWorkspace>,
#[serde(skip_serializing_if = "Vec::is_empty", default)]

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#[serde(skip_serializing_if = "Vec::is_empty", default)]
#[serde(default)]

no need since the type doesn't inherit Serialize.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants