{"id":28763326,"url":"https://github.com/smallstep/ssh-attest-proxy","last_synced_at":"2025-06-17T09:08:13.413Z","repository":{"id":288288233,"uuid":"967504156","full_name":"smallstep/ssh-attest-proxy","owner":"smallstep","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-22T21:06:32.000Z","size":3038,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-24T16:50:14.873Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/smallstep.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-04-16T14:55:31.000Z","updated_at":"2025-04-22T21:06:35.000Z","dependencies_parsed_at":"2025-04-16T22:44:13.973Z","dependency_job_id":"45e09aa0-3a36-4ce4-99d3-3c241673696a","html_url":"https://github.com/smallstep/ssh-attest-proxy","commit_stats":null,"previous_names":["smallstep/ssh-attest-proxy"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/smallstep/ssh-attest-proxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallstep%2Fssh-attest-proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallstep%2Fssh-attest-proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallstep%2Fssh-attest-proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallstep%2Fssh-attest-proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/smallstep","download_url":"https://codeload.github.com/smallstep/ssh-attest-proxy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/smallstep%2Fssh-attest-proxy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260326760,"owners_count":22992385,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-17T09:08:12.702Z","updated_at":"2025-06-17T09:08:13.388Z","avatar_url":"https://github.com/smallstep.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SSH SK Attestation Proxy\n\n**This is an educational project and is not suitable for production use.**\n\n## Background\n\nOpenSSH has `-sk` type keys that are designed to be generated and stored on hardware security keys. But, for privacy reasons, there is no way for a server to prove that any `-sk` key is actually stored in hardware and not exportable. Nor is it possible for a server to prove the hardware identity of a security key.\n\nFor this prototype project, we embed attestation information into an SSH certificate, so that a server can confirm the residency of the key:\n\n```\nid-cert.pub:\n        Type: sk-ssh-ed25519-cert-v01@openssh.com user certificate\n        Public key: SK-ED25519-CERT SHA256:3zjLLEQv8OELBVQwZLdzSlnqVYxq5aV3nZuqXVHtrzg\n        Signing CA: ED25519 SHA256:tZa6QeXJgtjXhBrOhiBsFpZRRBQDB6wzC01HX0i8JnE (using ssh-ed25519)\n        Key ID: \"key-attestation\"\n        Serial: 1\n        Valid: from 2025-04-28T14:12:18 to 2026-04-28T14:12:18\n        Principals:\n                carl\n        Critical Options: (none)\n        Extensions:\n                ssh-sk-attest-v01@step.sm AAAAEXAMPLEzaC1zay1hdHRlc3QtdjAxAAAELwAAABFzc2g...\n                permit-user-rc\n                permit-X11-forwarding\n                permit-agent-forwarding\n                permit-port-forwarding\n                permit-pty\n        Signature:\n                bd:50:e9:bc:c8:fe:...\n```\n\nThis project ensures that only hardware-backed and attested SSH certificates can be used to access an OpenSSH server. This could be extended to test attestation information against an inventory of devices that are allowed to SSH.\n\nThis could be run on an SSH bastion host (aka SSH jump box), to confirm attestations before passing a connection on to a final host. However, this project is not suitable for production deployments. A production version would implement key attestation verification in an SSH Certificate Authority, not on the SSH server itself.\n\nThere are two binaries:\n\n### Certificate issuer\n\n`ssh_ca_attest` is an SSH user certificate issuer. Given an SSH pubkey and attestation information, it signs an SSH `-sk` certificates with SSH attestation data embedded as a custom extension in the certificate.\n\nHere's an example where we generate certificates with attestation data, using a YubiKey:\n\n```\nssh-keygen -t ed25519 -f ca_key -N \"\"\ncurl -sLo ca.pem https://developers.yubico.com/PKI/yubico-piv-ca-1.pem\n\nstep crypto rand --format raw  128 \u003e challenge.bin\n\nssh-keygen -t ed25519-sk -f id -N \"\" -O challenge=challenge.bin -O write-attestation=attestation.bin\nbin/ssh_ca_attest ca_key id.pub attestation.bin challenge.bin \"carl\" id-cert.pub\n\nssh-keygen -t ecdsa-sk -f ecdsa_id -N \"\" -O challenge=challenge.bin -O write-attestation=ecdsa_attestation.bin\nbin/ssh_ca_attest ca_key ecdsa_id.pub ecdsa_attestation.bin challenge.bin \"carl\" ecdsa_id-cert.pub\n```\n\n### Server authorization\n\n`verify_ssh_ca_attestation` is the authorization component.\n\nIt's designed to run on an SSH server as a global `AuthorizedPrincipalsCommand`.\n\nTo verify the attestations in the certificates generated above, we need the Yubico FIDO root CA certificate:\n\n```\ncurl https://developers.yubico.com/PKI/yubico-fido-ca-1.pem -o yubico-ca.pem\n```\n\nThen:\n\n```\nbin/verify_ssh_sk_attestation --ca yubico-ca.pem carl $(\u003c id-cert.pub)\nbin/verify_ssh_sk_attestation --ca yubico-ca.pem carl $(\u003c ecdsa_id-cert.pub)\n```\n\nBoth will exit with code 0 on success.\nErrors are printed to stderr and logged to the systemd journal, with identifier `verify-ssh-sk`.\n\n#### Configuring SSHD\n\nYou can run this as an `AuthorizedPrincipalsCommand`, eg:\n\n```\nAuthorizedPrincipalsCommand /bin/verify_ssh_ca_attestation --ca /etc/ssh/yubico-fido-ca.pem %u %t %k\n```\n\nAny certificate without an attestation will be rejected.\nIf a certificate has an attestation, it will be verified.\nIf the `--ca` flag is passed, the attestation certificate must chain up to the root CA supplied.\nThe certificate principals are then printed.\n(If the certificate has empty principals, the connection is rejected.)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmallstep%2Fssh-attest-proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsmallstep%2Fssh-attest-proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsmallstep%2Fssh-attest-proxy/lists"}