{"id":13509685,"url":"https://github.com/square/sharkey","last_synced_at":"2025-06-13T01:39:57.528Z","repository":{"id":9797663,"uuid":"63361134","full_name":"square/sharkey","owner":"square","description":"Sharkey is a service for managing certificates for use by OpenSSH","archived":false,"fork":false,"pushed_at":"2023-09-12T02:07:29.000Z","size":34356,"stargazers_count":401,"open_issues_count":15,"forks_count":26,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-03-30T07:02:12.254Z","etag":null,"topics":["certificate","certificates","crypto","enterprise-software","openssh","pki","ssh","tofu","trust-on-first-use"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/square.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-07-14T18:44:39.000Z","updated_at":"2025-03-15T08:43:45.000Z","dependencies_parsed_at":"2024-06-20T12:59:33.874Z","dependency_job_id":"b83173d0-63f6-435e-9120-df0a0d4e2b90","html_url":"https://github.com/square/sharkey","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Fsharkey","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Fsharkey/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Fsharkey/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/square%2Fsharkey/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/square","download_url":"https://codeload.github.com/square/sharkey/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246324290,"owners_count":20759105,"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":["certificate","certificates","crypto","enterprise-software","openssh","pki","ssh","tofu","trust-on-first-use"],"created_at":"2024-08-01T02:01:11.458Z","updated_at":"2025-03-30T13:32:44.047Z","avatar_url":"https://github.com/square.png","language":"Go","funding_links":[],"categories":["Go","crypto"],"sub_categories":[],"readme":"![say no to TOFU](sharkey.png)\n\n# sharkey\n\n[![license](http://img.shields.io/badge/license-apache_2.0-blue.svg?style=flat)](https://raw.githubusercontent.com/square/certigo/master/LICENSE)\n![development status](https://img.shields.io/badge/status-alpha-orange.svg)\n[![tests](https://github.com/square/sharkey/actions/workflows/tests.yml/badge.svg)](https://github.com/square/sharkey/actions/workflows/tests.yml)\n[![report](https://goreportcard.com/badge/github.com/square/sharkey)](https://goreportcard.com/report/github.com/square/sharkey)\n\nSharkey is a service for managing certificates for use by OpenSSH.\n\n![sharks](dancing-sharks.png)\n\nSharkey has a client component and a server component. The server is\nresponsible for issuing signed host certificates, the client is responsible for\ninstalling host certificates on machines. Sharkey builds on the trust relationships\nof your existing X.509 PKI to manage trusted SSH certificates. Existing X.509\ncertificates can be minted into SSH certificates, so you don't have to maintain\ntwo separate PKI hierarchies.\n\n### Build\n\nCheck out the repository, and build client/server:\n\n    go build -o sharkey-client ./client\n    go build -o sharkey-server ./server\n\n### Server\n\nThe server component accepts requests and issues short lived host certificates.\n\nClients send their public key to the server (via TLS with mutual\nauthentication) periodically. The server authenticates the client by checking\nthat its certificate is valid for the requested hostname. If everything looks\ngood, the server will take the public key in the request and issue an OpenSSH\nhost certificate for the requested hostname.\n\nA log of all issued certificates is stored in a database. The server can\ngenerate a `known_hosts` file from the issuance log if required.  \n\nUsage:\n\n    usage: sharkey-server --config=CONFIG [\u003cflags\u003e] \u003ccommand\u003e [\u003cargs\u003e ...]\n\n    Certificate issuer of the ssh-ca system.\n\n    Flags:\n      --help           Show context-sensitive help (also try --help-long and --help-man).\n      --config=CONFIG  Path to config file for server.\n      --version        Show application version.\n\n    Commands:\n      help [\u003ccommand\u003e...]\n        Show help.\n\n      start\n        Run the sharkey server.\n\n      migrate [\u003cflags\u003e]\n        Set up database/run migrations.\n\nConfiguration (example):\n\n    # SQLite database\n    # ---\n    db:\n      address: /path/to/sharkey.db\n      type: sqlite\n\n    # MySQL database\n    # ---\n    # db:\n    #   username: root\n    #   password: password\n    #   address: hostname:port\n    #   schema: ssh_ca\n    #   type: mysql\n    #   tls:                                       # MySQL TLS config (optional)\n    #     ca: /path/to/mysql-ca-bundle.pem\n    #     cert: /path/to/mysql-client-cert.pem     # MySQL client cert\n    #     key: /path/to/mysql-client-cert-key.pem  # MySQL client cert key\n\n    # Server listening address\n    listen_addr: \"0.0.0.0:8080\"\n\n    # TLS config for serving requests\n    # ---\n    tls:\n      ca: /path/to/ca-bundle.pem\n      cert: /path/to/server-certificate.pem\n      key: /path/to/server-certificate-key.pem\n\n    # Signing key (from ssh-keygen)\n    signing_key: /path/to/ca-signing-key\n\n    # Lifetime/validity duration for generated host certificates\n    host_cert_duration: 168h\n\n    # Lifetime/validity duration for generated user certificates\n    user_cert_duration: 24h\n\n    # Optional suffix to strip from client hostnames when generating certificates.\n    # This is useful if all your machines have a common TLD/domain, and you want to\n    # include an alias in the generated certificate that doesn't include that suffix.\n    # Leave empty to disable\n    strip_suffix: \".example.com\"\n\n    # Optional set of aliases for hosts. If a hostname matches an alias entry, the\n    # listed principals will be added to its certificate. This is useful if you have\n    # special hosts that are accessed via CNAME records.\n    aliases:\n      \"host.example.com\":\n        - \"alias1.example.com\"\n        - \"alias2.example.com\"\n\n    # Optional set of extra entries to provide to clients when they fetch a known_hosts\n    # file. This is useful if you have externally-managed servers in your infrastructure\n    # that you want to tell clients about, of if you want to add CA entries to the\n    # known_hosts file.\n    extra_known_hosts:\n      - \"@cert-authority *.example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDBwhA8rKPESjDy4iqTlkBqUlBU2xjwtmFUHY6cutA9TYbB5H/mjxzUpnSNw/HyFWNpysjTSQtHWWBdJdJGU/0aDgFUwbduHeDFxviGVSkOxm2AYn7XJopzITZRqmAmsYXHUBa75RQb+UgIG7EpCoi8hF4ItJV+TT777j1irkXwlMmeDiJEaA+7bPNdUdGw8zRbk0CyeotYVD0griRtkXdfgnQAu+DvBwOuW/uiZaPz/rAVjt4b9fmp6pcFKI3RsBqqn5tQVhKCPVuSwqvIQ7CTVkMClYovlH1/zGe8PG1DHbM9irP98S5j3mVD9W5v3QILpsg24RIS14M8pLarlD6t root@authority\"\n\n    # User certs are issued to users who connect through an authenticating proxy\n    # That user should connect with a user certificate and set the username\n    # in a header.\n    auth_proxy:\n      # Hostname is validated against the incoming user certificate\n      hostname: proxy.example.com\n      # The HTTP header containing the username\n      username_header: X-Forwarded-User\n\n    # Optional settings related to SSH\n    ssh:\n      # List of extensions that should be set on the user certificate (default is no extensions)\n      user_cert_extensions:\n        - \"permit-X11-forwarding\"\n        - \"permit-agent-forwarding\"\n        - \"permit-port-forwarding\"\n        - \"permit-pty\"\n        - \"permit-user-rc\"\n\nA signing key for generating host certificates can be generated with `ssh-keygen`.\n\n#### Database\n\nSharkey supports both SQLite and MySQL. There is a built-in command in the\nserver binary to manage migrations (based on [goose][goose]).\n\nTo run migrations on a configured database:\n\n    # SQLite\n    ./sharkey-server --config=[CONFIG] migrate --migrations=db/sqlite\n\n    # MySQL\n    ./sharkey-server --config=[CONFIG] migrate --migrations=db/mysql\n\nYou can also manage migrations using the [goose][goose] command-line utility.\nSee the [goose][goose] documentation for more info.\n\n[goose]: https://bitbucket.org/liamstask/goose\n\n### Client\n\nThe client component periodically requests a new host certificate from the\nserver and installs it on the machine.\n\nThe client will use a TLS client certificate to make a connection to the server\nand authenticate itself. This assumes that there is a long-lived certificate\nand key installed on each machine that uses the client. We then periodically\nread the host key for the locally running OpenSSH (`host_key`), send it to the\nserver, and retrieve a signed host certificate based on that key. The signed\nhost certificate is then installed on the machine (`signed_cert`).\n\nUsage:\n\n    usage: sharkey-client --config=CONFIG [\u003cflags\u003e]\n\n    Flags:\n      --help           Show context-sensitive help (also try --help-long and --help-man).\n      --config=CONFIG  Path to yaml config file for setup\n      --version        Show application version.\n\nConfiguration (example):\n\n    # Server address\n    request_addr: \"https://sharkey-server.example:8080\"\n\n    # TLS config for making requests\n    # ---\n    tls:\n      ca: /path/to/ca-bundle.pem\n      cert: /path/to/client-certificate.pem\n      key: /path/to/client-certificate-key.pem\n\n    # List of host keys for OpenSSH server\n    host_keys:\n      # Here, 'key' is the public key, and 'cert' is where to install the signed cert\n      - plain: \"/etc/ssh/ssh_host_rsa_key.pub\"\n        signed: \"/etc/ssh/ssh_host_rsa_key-cert.pub\"\n      # You can specify multiple host keys (e.g. if you have both RSA, ED25519 keys)\n      - plain: \"/etc/ssh/ssh_host_ed25519_key.pub\"\n        signed: \"/etc/ssh/ssh_host_ed25519_key-cert.pub\"\n\n    # Where to install the known_hosts file\n    known_hosts: /etc/ssh/known_hosts\n\n    # If set to true, only install authorities in known_hosts file (ignore other machine's host keys).\n    known_hosts_authorities_only: false\n\n    # How often to refresh/request new certificate\n    sleep: \"24h\"\n\n    # Path to sudo binary on client host\n    # Uses sudo to write known_hosts and signed_cert.pub if this field specified\n    sudo: \"/usr/bin/sudo\"\n\n    # Command to restart ssh daemon for the host\n    # If sudo is set as well, this command will be prefixed with 'sudo'\n    ssh_reload: [\"/usr/sbin/service\", \"ssh\", \"restart\"]\n\nOpenSSH will have to be configured to read the signed host certificate (this is\nwith the `HostCertificate` config option in `sshd_config`). If the signed host\ncertificate is missing from disk, OpenSSH will fall back to TOFU with the\ndefault host key. Therefore, it should always be safe to configure a host\ncertificate; even if the Sharkey client fails you can still SSH into your\nmachine.\n\n### User Certificates\n\nFor a user to SSH into an openssh server, they can present a certificate, which\nshould have a principal matching their username.\nSharkey outsources identifying users to an SSO proxy.  That proxy needs to\nconnect to sharkey over mTLS.  You can configure the DNS SAN that should appear\non the server's client cert (eg, proxy.example.com) and the HTTP header it sets\nthe username to (eg, X-Forwarded-User).  See example configs.\n\nNo client helper is included with Sharkey at this time, so you have to set up\na script yourself at this time to enroll the user.\n\nTesting looks something like this:\n   `curl --cert proxy.crt --key proxy.key https://localhost:8080/enroll_user -H \"X-Forwarded-User: bob\" -d @~/.ssh/bob.pub`\n\nBut in production use you'd expect it more like\n   `curl \u003cauth to your proxy\u003e https://ssoproxy.example.com/enroll_user -d @~/.ssh/bob.pub`\n\n### GitHub SSH CA Support\n\nSharkey supports issuing user certificates that are compatible with GitHub SSH CA format by:\n\n- Mapping a GitHub username to a SAML identity\n- Including appropriate GitHub username in each certificate\n\nGitHub supports authentication using SSH certificates for Enterprise Cloud accounts. The only requirement is that certificates include GitHub usernames, so that they can be matched to a particular user.\n\nSharkey already requires SSO proxy for the user certificate feature. Additionally, the GitHub integration requires that the GitHub organization is configured with SSO (i.e. non-GitHub) access.\n\nAn example config with GitHub SSH CA Support enabled can be found in `test/git_server_config.yaml`.\nA GitHub App with read/write access to `Organization:members` is required. \n\nSharkey will periodically query GitHub for a mapping of SAML identities to GitHub usernames and store it in Sharkey's DB. \nWhen issuing a certificate, Sharkey will check the DB and if a mapping exists, attaches it to the certificate as an extension.\n\nAn example cert is shown below:\n```\n        Type: ssh-rsa-cert-v01@openssh.com user certificate\n        Public key: RSA-CERT SHA256:Eabuov2aAPLhN1FscJ6P3Lle85N6Txhj4sy4ALTkG6M\n        Signing CA: ED25519 SHA256:HYgRf1dHbVtWY/e3jjfnAlwvAPPBKYxdXz8SDfhlAws (using ssh-ed25519)\n        Key ID: \"alice\"\n        Serial: 1\n        Valid: from 2020-07-31T16:10:25 to 2020-08-01T16:10:25\n        Principals:\n                alice\n        Critical Options: (none)\n        Extensions:\n                login@github.com UNKNOWN OPTION (len 5)\n                permit-X11-forwarding\n                permit-agent-forwarding\n                permit-port-forwarding\n                permit-pty\n                permit-user-rc\n```\n\n### Telemetry\n \nSharkey supports sending DogStatsD metrics. Currently only metrics regarding GitHub SSH CA are being emitted.\nAdding the following block to the server configuration will enable metrics:\n```\ntelemetry:\n  address: \"127.0.0.1:8200\"\n``` \nUnix sockets are also supported.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquare%2Fsharkey","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsquare%2Fsharkey","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsquare%2Fsharkey/lists"}