{"id":13551458,"url":"https://github.com/cloudtools/ssh-cert-authority","last_synced_at":"2025-04-04T12:07:23.059Z","repository":{"id":30067512,"uuid":"33616975","full_name":"cloudtools/ssh-cert-authority","owner":"cloudtools","description":"An implementation of an SSH certificate authority.","archived":false,"fork":false,"pushed_at":"2021-08-11T20:41:43.000Z","size":230,"stargazers_count":736,"open_issues_count":18,"forks_count":71,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-03-28T11:07:34.883Z","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":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudtools.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.rst","support":null}},"created_at":"2015-04-08T15:56:22.000Z","updated_at":"2025-03-24T07:00:18.000Z","dependencies_parsed_at":"2022-08-09T09:15:27.874Z","dependency_job_id":null,"html_url":"https://github.com/cloudtools/ssh-cert-authority","commit_stats":null,"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudtools%2Fssh-cert-authority","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudtools%2Fssh-cert-authority/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudtools%2Fssh-cert-authority/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudtools%2Fssh-cert-authority/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudtools","download_url":"https://codeload.github.com/cloudtools/ssh-cert-authority/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247174418,"owners_count":20896078,"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":"2024-08-01T12:01:48.662Z","updated_at":"2025-04-04T12:07:23.012Z","avatar_url":"https://github.com/cloudtools.png","language":"Go","funding_links":[],"categories":["Go","others"],"sub_categories":[],"readme":"==================\nssh-cert-authority\n==================\n\nIntroduction\n============\n\nA democratic SSH certificate authority.\n\nOperators of ssh-cert-authority want to use SSH certificates to provide\nfine-grained access control to servers they operate, enforce the 2-person rule,\nkeep their certificate signing key a secret and not need to be required to get\ninvolved to actually sign certificates. A tall order.\n\nThe idea here is that a user wishing to access a server runs\n``ssh-cert-authority request`` and specifies a few parameters for the cert\nrequest like how long he/she wants it to be valid for. This is POSTed to\nthe ``ssh-cert-authority runserver`` daemon which validates that the\ncertificate request was signed by a valid user (configured on the daemon\nside) before storing a little state and returning a certificate id to\nthe requester.\n\nThe requester then convinces one or more of his or her authorized\nfriends (which users are authorized and the number required is\nconfigured on the daemon side) to run the ``ssh-cert-authority sign``\ncommand specifying the request id. The signer is allowed to see the\nparameters of the certificate before deciding whether or not to actually\nsign the cert request. The signed certificate is again POSTed back to\nthe server where the signature is validated.\n\nNote that a requester may not sign their own request. If a +1 is\nreceived for a request by the same key as the one in the request then\nthe signing request is rejected.\n\nOnce enough valid signatures are received the cert request is\nautomatically signed using the signing key for the cert authority and\nmade available for download by the requester using the request id.\n\nNone of the code here ever sees or even attempts to look at secrets. All\nsigning operations are performed by ``ssh-agent`` running on respective\nlocal machines. In order to bootstrap the signing daemon you must\n``ssh-add`` the signing key. In order to request a cert or sign someone's\ncert request the user must have the key used for signing loaded up in\n``ssh-agent``. Secrets are really hard to keep, we'll leave them in the\nmemory space of ``ssh-agent``.\n\nBackground\n==========\n\nIn general the authors of this project believe that SSH access to hosts\nrunning in production is a sometimes-necessary evil. We prefer systems\nthat are capable of resolving faults by themselves and that are always\nfault tolerant. However, when things go wrong or when tools for\nmanaging the system without SSH have not been built we recognize that\ngetting on the box is often the only option remaining to attempt to\nrestore service.\n\nSSH access to hosts in dynamic datacenters like those afforded by Amazon\nWeb Services and Google Compute poses its own challenges. Instances may\nbe spun up or torn down at any time. Typically organizations do one of\ntwo things to facilitate SSH access to instances:\n\n    - Generate an SSH keypair and share it amongst anyone that may need\n      to access production systems\n    - Put everyone's public key into an ``authorized_keys`` file (perhaps\n      baked into an AMI, perhaps via cloudinit)\n\nIn security conscience environments organizations may have built a tool\nthat automates the process of adding and removing public keys from an\n``authorized_keys`` file.\n\nNone of these options are great. The first two options do not meet the\nsecurity requirements of the author's employer. Sharing secrets is\nsimply unacceptable and it means that an ex-employee now has access to\nsystems that he or she shouldn't have access to until the key can be\nrotated out of use.\n\nManaging a large ``authorized_keys`` file is a problem because it isn't\nlimited to the exact set of people that require access to nodes right\nnow.\n\nAs part of our ISO 27001 certification we are additionally required to:\n\n    - Automatically revoke access to systems when engineers no longer\n      need access to them.\n    - Audit who accessed which host when and what they did\n\nSSH certificates solve these problems and more.\n\nAn OpenSSH certificate is able to encode a set of permissions of the\nform (see also the ``CERTIFICATES`` section of ``ssh-keygen(1)``):\n\n    - Which user may use this certificate\n    - The user id of the user\n    - When access to servers may begin\n    - When access to servers expires\n    - Whether or not the user may open a PTY, do port forwarding or SSH\n      agent forwarding.\n    - Which servers may be accessed\n\nThe certificate is signed by some trusted authority (an SSH private key)\nand machines within the environment are told to trust any certificate\nsigned by that authority. This is very, very similar to how trust works\nfor TLS certificates on your favorite websites.\n\nA piece of trivia is that SSH certificates are not X.509 certs, they're\ninstead more along the lines of a tag-length-value encoding of a C\nstruct.\n\nUsing OpenSSH Certificates\n==========================\n\nThis section describes using OpenSSH certificates manually, without the\nssh-cert-authority tool.\n\nTo begin using OpenSSH certificates you first must generate an ssh key\nthat will be kept secret and used as the certificate authority in your\nenvironment. This can be done with a command like::\n\n    ssh-keygen -f my_ssh_cert_authority\n\nThat command outputs two files::\n\n    my_ssh_cert_authority: The encrypted private key for your new authority\n    my_ssh_cert_authority.pub: The public key for your new authority.\n\nBe sure you choose a passphrase when prompted so that the secret is\nstored encrypted. Other options to ``ssh-keygen`` are permitted including\nboth key type and key parameters. For example, you might choose to use\nECDSA keys instead of RSA.\n\nGrab the fingerprint of your new CA::\n\n    $ ssh-keygen -l -f my_ssh_cert_authority\n    2048 2b:a1:16:84:79:0a:2e:38:84:6f:32:96:ab:d4:af:5d my_ssh_cert_authority.pub (RSA)\n\nNow that you have a certificate authority you'll need to tell the hosts\nin your environment to trust this authority. This is done very similar\nto user SSH keys by setting up the ``authorized_keys`` on your hosts (the\nexpectation is that you're setting this up at launch time via cloudinit\nor perhaps baking the change into an OS image or other form of snapshot).\n\nYou have a choice of putting this ``authorized_keys`` file into\n``$HOME/.ssh/authorized_keys`` or the change can be made system wide. For\nsystem wide configuration see ``sshd_config(5)`` and the\n``TrustedUserCAKeys`` option.\n\nIf you are modifying the user's ``authorized_keys`` file simply add a new\nline to ``authorized_keys`` of the form::\n\n    cert-authority \u003cpaste the single line from my_ssh_cert_authority.pub\u003e\n\nA valid line might look like this for an RSA key::\n\n    cert-authority ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAYQC6Shl5kUuTGqkSc8D2vP2kls2GoB/eGlgIb0BnM/zsIsbw5cWsPournZN2IwnwMhCFLT/56CzT9ZzVfn26hxn86KMpg76NcfP5Gnd66dsXHhiMXnBeS9r6KPQeqzVInwE=\n\nAt this point your host has been configured to accept a certificate\nsigned by your authority's private key. Let's generate a certificate for\nourselves that permits us to login as the user ubuntu and that is valid\nfor the next hour (This assumes that our personal public SSH key is\nstored at ``~/.ssh/id_rsa.pub)`` ::\n\n    ssh-keygen -V +1h -s my_ssh_cert_authority -I bvanzant -n ubuntu ~/.ssh/id_rsa.pub\n\nThe output of that command is the file ``~/.ssh/id_rsa-cert.pub``. If you\nopen it it's just a base64 encoded blob. However, we can ask ``ssh-keygen``\nto show us the contents::\n\n    $ ssh-keygen -L -f ~/.ssh/id_rsa-cert.pub\n    /tmp/test_main_ssh-cert.pub:\n        Type: ssh-rsa-cert-v01@openssh.com user certificate\n        Public key: RSA-CERT f6:e3:42:5e:72:85:ce:26:e8:45:1f:79:2d:dc:0d:52\n        Signing CA: RSA 4c:c6:1e:31:ed:7b:7c:33:ff:7d:51:9e:59:da:68:f5\n        Key ID: \"bvz-test\"\n        Serial: 0\n        Valid: from 2015-04-13T06:48:00 to 2015-04-13T07:49:13\n        Principals:\n                ubuntu\n        Critical Options: (none)\n        Extensions:\n                permit-X11-forwarding\n                permit-agent-forwarding\n                permit-port-forwarding\n                permit-pty\n                permit-user-rc\n\nLet's use the certificate now::\n\n    # Add the key into our ssh-agent (this will find and add the certificate as well)\n    ssh-add ~/.ssh/id_rsa\n    # And SSH to a host\n    ssh ubuntu@\u003cthe host where you modified authorized_keys\u003e\n\nIf the steps above were followed carefully you're now SSHed to the\nremote host. Fancy?\n\nAt this point if you look in ``/var/log/auth.log`` (Ubuntu) (``/var/log/secure``\non Red Hat based systems) you'll see that the user ubuntu logged in to this\nmachine. This isn't very useful data. If you change the sshd_config on your \nservers to include ``LogLevel VERBOSE`` you'll see that the certificate key id\nis also logged when a user logs in via certificate. This allows you to map\nthat user ``bvanzant`` logged into the host using username ubuntu. This will\nmake your auditors happy.\n\nYou're now an SSH cert signer. The problem, however, is that you\nprobably don't want to be the signer. Signing certificates is not fun.\nAnd it's really not fun at 3:00AM when someone on the team needs to\naccess a host for a production outage and you were not that person. That\nperson now has to wake you up to get a certificate signed. And you\nprobably don't want that. And now you perhaps are ready to appreciate\nthis project a bit more.\n\nSetting up ssh-cert-authority\n=============================\n\nThis section is going to build off of parts of the prior section. In\nparticular it assumes that you have configured an SSH authority already\nand that you know how to configure servers to accept your certificates.\n\nssh-cert-authority is a single tool that has subcommands (the decision\nto do this mostly came from trying to follow Go's preferred way of\nbuilding and distributing software). The subcommands are:\n\n    - runserver\n    - request\n    - sign\n    - get\n    - encrypt-key\n    - generate-config\n\nAs you might have guessed by now this means that a server needs to be\nrunning and serving the ssh-cert-authority service. Users that require\nSSH certificates will need to be able to access this service in order to\nrequest, sign and get certificates.\n\nThis tool was built with the idea that organizations have more than one\nenvironment with perhaps different requirements for obtaining and using\ncertificates. For example, there might be a test environment, a staging\nenvironment and a production environment. Throughout the examples we\nassume a single environment named \"production.\"\n\nIn all cases this tool relies heavily on ``ssh-agent``. It is entirely\nfeasible that ``ssh-agent`` could be replaced by any other process capable\nof signing a blob of data with a specified key including an HSM.\n\nMany of the configuration files use SSH key fingerprints. To get a key's\nfingerprint you may run ``ssh-keygen -l -f \u003cfilename\u003e`` or, if the key is\nalready stored in your ``ssh-agent`` you can ``ssh-agent -l``.\n\nSetting up the daemon\n---------------------\n\nssh-cert-authority uses json for its configuration files. By default the\ndaemon expects to find its configuration information in\n``$HOME/.ssh_ca/sign_certd_config.json`` (you can change this with a\ncommand line argument). A valid config file for our production\nenvironment might be::\n    {\n      \"production\": {\n            \"NumberSignersRequired\": 1,\n            \"MaxCertLifetime\": 86400,\n            \"SigningKeyFingerprint\": \"66:b5:be:e5:7e:09:3f:98:97:36:9b:64:ec:ea:3a:fe\",\n            \"AuthorizedSigners\": {\n                \"66:b5:be:e5:7e:09:3f:98:97:36:9b:64:ec:ea:3a:fe\": \"bvz\"\n            },\n            \"AuthorizedUsers\": {\n                \"1c:fd:36:27:db:48:3f:ad:e2:fe:55:45:67:b1:47:99\": \"bvz\"\n            }\n      }\n    }\n\nEffectively the format is::\n\n    {\n        \"environment name\": {\n            NumberSignersRequired\n            MaxCertLifetime\n            SigningKeyFingerprint\n            PrivateKeyFile\n            KmsRegion\n            AuthorizedSigners {\n                \u003ckey fingerprint\u003e: \u003ckey identity\u003e\n            }\n            AuthorizedUsers {\n                \u003ckey fingerprint\u003e: \u003ckey identity\u003e\n            }\n    }\n\n- ``NumberSignersRequired``: The number of people that must sign a request\n  before the request is considered complete and signed by the authority.\n  If this field is \u003c 0 valid certificate requests will be automatically\n  signed at request time. It is highly recommended that if auto signing\n  is enabled a ``MaxCertLifetime`` be specified.\n- ``MaxCertLifetime``: The maximum duration certificate, measured from Now()\n  in seconds, that is permitted. The default is 0, meaning unlimited. A\n  value of 86400 would mean that the server will reject requests for\n  certificates that are valid for more than 1 day.\n- ``SigningKeyFingerprint``: The fingerprint of the key that will be used to\n  sign complete requests. This should be the fingerprint of your CA. When using\n  this option you must, somehow, load the private key into the agent such that\n  the daemon can use it.\n- ``PrivateKeyFile``: A path to a private key file or a Google KMS key url.\n\n  If you have specified a file system path the key may be unencrypted or have\n  previousl been encrypted using Amazon's KMS. If the key was encrypted using\n  KMS simply name it with a \".kms\" extension and ssh-cert-authority will\n  attempt to decrypt the key on startup. See the section on Encrypting a CA Key\n  for help in using KMS to encrypt the key.\n\n  If you specified a Google KMS key it should be of the form:\n  ``gcpkms:///projects/\u003cproject-name\u003e/locations/\u003cregion|global\u003e/keyRings/\u003ckeyring\n  name\u003e/cryptoKeys/\u003ckeyname\u003e/cryptoKeyVersions/\u003cversion-number\u003e``\n\n- ``KmsRegion``: If sign_certd encounters a privatekey file with an\n  extension of \".kms\" it will attempt to decrypt it using KMS in the\n  same region that the software is running in. It determines this using\n  the local instance's metadata server. If you're not running\n  ssh-cert-authority within AWS or if the key is in a different region\n  you'll need to specify the region here as a string, e.g. us-west-2.\n- ``AuthorizedSigners``: A hash keyed by key fingerprints and values of key\n  ids. I recommend this be set to a username. It will appear in the\n  resultant SSH certificate in the KeyId field as well in\n  ssh-cert-authority log files. The ``AuthorizedSigners`` field is used to\n  indicate which users are allowed to sign requests.\n- ``AuthorizedUsers``: Same as ``AuthorizedSigners`` except that these are\n  fingerprints of people allowed to submit requests.\n- ``CriticalOptions``: A hash of critical options to be added to all\n  certificate requests. By specifying these in your configuration file\n  all cert requests to this environment will have these options embedded\n  in them. You can use this option, for example, to restrict the IP\n  addresses that are allowed to use a certificate or to force a user\n  to only be able to run a single command. Those are the only two\n  options supported by sshd right now. This document describes them in\n  the section ``Critical options``:\n  http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD\n\nThe same users and fingerprints may appear in both ``AuthorizedSigners`` and\n``AuthorizedUsers``.\n\nYou're now ready to start the daemon. I recommend putting this under the\ncontrol of some sort of process monitor like upstart or supervisor or\nwhatever suits your fancy.::\n\n    ssh-cert-authority runserver\n\nLog messages go to stdout. When the server starts it prints its config\nfile as well as the location of the ``$SSH_AUTH_SOCK`` that it found\n\nIf you are running this from within a process monitor getting a\nfunctioning ``ssh-agent`` may not be intuitive. I run it like this::\n\n    ssh-agent ssh-cert-authority runserver\n\nThis means that a new ``ssh-agent`` is used exclusively for the server. And\nthat means that every time the service starts (or restarts) you must\nmanually add your signing keys to the agent via ``ssh-add``. To help  with\nthis the server prints the socket it's using::\n\n    2015/04/12 16:05:05 Using SSH agent at /private/tmp/com.apple.launchd.MzybvK44OP/Listeners\n\nYou can take that value and add in your keys like so::\n\n    SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.MzybvK44OP/Listeners ssh-add path-to-ca-key\n\nOnce the server is up and running it is bound to 0.0.0.0 on port 8080.\n\nRunning behind a reverse proxy (e.g. nginx)\n-------------------------------------------\n\nIf you're running behind a reverse proxy, which this project recommends,\nyou will want to set one additional command line argument,\n``reverse-proxy``. You can instead set the environment variable\nSSH_CERT_AUTHORITY_PROXY=true if that is more your style. Setting this\nflag to true instructs the daemon to trust the X-Forwarded-For header\nthat nginx will set and to use that IP address in log messages. Know\nthat you must not set this value to true if you are not running behind a\nproxy as this allows a malicious user to control the value of the IP\naddress that is put into your log files.\n\nCommand Line Flags\n------------------\n\n- ``config-file``: The path to a config.json file. Used to override the\n  default of $HOME/.ssh_ca/sign_certd_config.json\n- ``listen-address``: Controls the bind address of the daemon. By\n  default we bind to localhost which means you will not be able to\n  connect to the daemon from hosts other than this one without using a\n  reverse proxy (e.g. nginx) in front of this daemon. A reverse proxy is\n  the recommended method for running this service in production.\n- ``reverse-proxy``: When specified the daemon will trust the\n  X-Forwarded-For header as added to requests by your reverse proxy.\n  This flag must not be set when you are not using a reverse proxy as it\n  permits a malicious user to control the IP address that is written to\n  log files.\n\nStoring Your CA Signing Key in Google Cloud\n===========================================\nGoogle Cloud KMS supports signing operations and ssh-cert-authority can use\nthese keys to sign the SSH certificates it issues. If you do this you'll likely\nwant to have your ssh-cert-authority running on an instance in GCP and\nconfigured with a service account that can use the key.\n\nssh-cert-authority has been tested with ecdsa keys from prime256v1 both\nsoftware and hardware backed. Other key kinds and curves might work.\n\nThis example assumes you have a functioning gcloud already.\n\nSetting up keys::\n\n  # First create a keyring to store keys\n  gcloud kms keyrings create ssh-cert-authority-demo --location us-central1\n\n  # Create keys on that keyring for dev and prod\n  gcloud alpha kms keys create --purpose asymmetric-signing --keyring ssh-cert-authority-demo \\\n    --location us-central1 --default-algorithm ec-sign-p256-sha256 dev\n  gcloud alpha kms keys create --purpose asymmetric-signing --keyring ssh-cert-authority-demo \\\n    --location us-central1 --default-algorithm ec-sign-p256-sha256 prod\n\n  # Create a service account for the system\n  gcloud iam service-accounts create ssh-cert-authority-demo\n\n  # If you're using a GCP instance you should launch your instance and specify\n  # that service account as the account for the instance. If you're running\n  # this on a local machine or an AWS instance or something you will need to\n  # explicitly get the service account key\n  gcloud iam service-accounts keys create ssh-cert-authority-demo-serviceaccount.json\n      --iam-account ssh-cert-authority-demo@YOUR_GOOGLE_PROJECT_ID.iam.gserviceaccount.com\n  \n  # You need to set that key file in an environment variable now:\n  export GOOGLE_APPLICATION_CREDENTIALS=/path/to/ssh-cert-authority-demo-serviceaccount.json\n\n  # Give that service account permission to use our newly created keys:\n  gcloud kms keys add-iam-policy-binding  ssh-cert-authority-dev-hsm --location us-central1 \\\n      --keyring ssh-cert-authority-demo \\\n      --member serviceAccount:ssh-cert-authority-demo@YOUR_GOOGLE_PROJECT_ID.iam.gserviceaccount.com \\\n      --role roles/cloudkms.signerVerifier\n\n  # Get the path to the keys we created:\n  gcloud kms keys list --location us-central1 --keyring ssh-cert-authority-demo\n\n  # That will print out the two keys we created earlier including the name of\n  # the key. The name of the key is a big path that begins with projects/. We\n  # need to copy this entire path into our sign_certd_config.json as the\n  # PrivateKeyFile for the environment. A minimal example showing only dev:\n  \n  {\n    \"dev\": {\n        \"NumberSignersRequired\": -1,\n        \"MaxCertLifetime\": 86400,\n        \"PrivateKeyFile\": \"gcpkms:///projects/YOUR_GOOGLE_PROJECT_ID/locations/us-central1/keyRings/ssh-cert-authority-demo/cryptoKeys/dev/cryptoKeyVersions/1\",\n        \"AuthorizedSigners\": {\n            \"a7:64:9e:35:5d:ae:c6:bd:79:f1:e3:c8:92:0b:9a:51\": \"bvz\"\n        },\n        \"AuthorizedUsers\": {\n            \"a7:64:9e:35:5d:ae:c6:bd:79:f1:e3:c8:92:0b:9a:51\": \"bvz\"\n        }\n    }\n  }\n\n\nEncrypting a CA Key Using Amazon's KMS\n======================================\n\nAmazon's KMS (Key Management Service) provides an encryption key\nmanagement service that can be used to encrypt small chunks of arbitrary\ndata (including other keys). This project supports using KMS to keep the\nCA key secure.\n\nThe recommended deployment is to launch ssh-cert-authority onto an EC2\ninstance that has an EC2 instance profile attached to it that allows it\nto use KMS to decrypt the CA key. A sample cloudformation stack is\nforthcoming to do all of this on your behalf.\n\nCreate Instance Profile\n-----------------------\n\nIn the mean time you can set things up by hand. A sample EC2 instance\nprofile access policy::\n\n    {\n        \"Statement\": [\n            {\n                \"Resource\": [\n                    \"*\"\n                ],\n                \"Action\": [\n                    \"kms:Encrypt\",\n                    \"kms:Decrypt\",\n                    \"kms:ReEncrypt\",\n                    \"kms:GenerateDataKey\",\n                    \"kms:DescribeKey\"\n                ],\n                \"Effect\": \"Allow\"\n            }\n        ],\n        \"Version\": \"2012-10-17\"\n    }\n\nCreate KMS Key\n--------------\n\nCreate a KMS key in the AWS IAM console. When specifying key usage allow the\ninstance profile you created earlier to use the key. The key you create\nwill have an id associated with it, it looks something like this::\n\n    arn:aws:kms:us-west-2:123412341234:key/debae348-3666-4cc7-9d25-41e33edb2909\n\nSave that for the next step.\n\nLaunch Instance\n---------------\n\nNow launch an instance and use the EC2 instance profile. A t2 class instance is\nlikely sufficient. Copy over the latest ssh-cert-authority binary (you\ncan also use the container) and generate a new key for the CA using\nssh-cert-authority. The nice thing here is that the key is never written\nanywhere unencrypted. It is generated within ssh-cert-authority,\nencrypted via KMS and then written to disk in encrypted form. ::\n\n    environment_name=production\n    ssh-cert-authority encrypt-key --generate-rsa \\\n        --key-id arn:aws:kms:us-west-2:881577346222:key/d1401480-8220-4bb7-a1de-d03dfda44a13 \\\n        --output ca-key-${environment}.kms\n\nThe output of this is two files: ``ca-key-production.kms`` and\n``ca-key-production.kms.pub``. The kms file should be referenced in the ssh\ncert authority config file, as documented elsewhere in this file, and\nthe .pub file will be used within authorized_keys on servers you wish to\nSSH to.\n\n``--generate-rsa`` will generate a 4096 bit RSA key. ``--generate-ecdsa`` will\ngenerate a key from nist's p384 curve.\n\nRequesting Certificates\n=======================\n\nSee USAGE.rst in this directory.\n\nSigning Requests\n================\n\nSee USAGE.rst in this directory.\n\nAll in one basic happy test case::\n\n    go build \u0026\u0026 reqId=$(./ssh-cert-authority request --reason testing --environment test --quiet) \u0026\u0026 \\\n    ./ssh-cert-authority sign --environment test --cert-request-id $reqId \u0026\u0026 \\\n    ./ssh-cert-authority get --add-key=false --environment test $reqId`\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudtools%2Fssh-cert-authority","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudtools%2Fssh-cert-authority","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudtools%2Fssh-cert-authority/lists"}