{"id":13582473,"url":"https://github.com/cloudposse/github-authorized-keys","last_synced_at":"2025-07-28T19:38:18.523Z","repository":{"id":56608792,"uuid":"74638991","full_name":"cloudposse/github-authorized-keys","owner":"cloudposse","description":"Use GitHub teams to manage system user accounts and authorized_keys","archived":false,"fork":false,"pushed_at":"2024-06-19T21:59:00.000Z","size":301,"stargazers_count":147,"open_issues_count":9,"forks_count":27,"subscribers_count":14,"default_branch":"main","last_synced_at":"2025-03-24T21:51:08.054Z","etag":null,"topics":["authorized-keys","docker","dockerfile","github","ssh","teams","user-management"],"latest_commit_sha":null,"homepage":"https://cloudposse.com","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/cloudposse.png","metadata":{"funding":{"github":"cloudposse"},"files":{"readme":"README.md","changelog":null,"contributing":"docs/contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2016-11-24T04:52:43.000Z","updated_at":"2025-02-02T22:05:42.000Z","dependencies_parsed_at":"2024-02-01T22:03:47.669Z","dependency_job_id":"aefebb32-50f0-4ca5-8f9d-04370709720b","html_url":"https://github.com/cloudposse/github-authorized-keys","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudposse%2Fgithub-authorized-keys","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudposse%2Fgithub-authorized-keys/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudposse%2Fgithub-authorized-keys/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudposse%2Fgithub-authorized-keys/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudposse","download_url":"https://codeload.github.com/cloudposse/github-authorized-keys/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248322600,"owners_count":21084337,"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":["authorized-keys","docker","dockerfile","github","ssh","teams","user-management"],"created_at":"2024-08-01T15:02:45.122Z","updated_at":"2025-04-11T01:10:28.594Z","avatar_url":"https://github.com/cloudposse.png","language":"Go","readme":"# Github Authorized Keys [![Build Status](https://travis-ci.org/cloudposse/github-authorized-keys.svg?branch=master)](https://travis-ci.org/cloudposse/github-authorized-keys)\n\nUse GitHub teams to manage system user accounts and `authorized_keys`.\n\n[![Go Report Card](https://goreportcard.com/badge/github.com/cloudposse/github-authorized-keys)](https://goreportcard.com/report/github.com/cloudposse/github-authorized-keys)\n[![Coverage Status](https://coveralls.io/repos/github/cloudposse/github-authorized-keys/badge.svg?branch=master)](https://coveralls.io/github/cloudposse/github-authorized-keys?branch=master)\n[![Docker Pulls](https://img.shields.io/docker/pulls/cloudposse/github-authorized-keys.svg)](https://hub.docker.com/r/cloudposse/github-authorized-keys)\n[![GitHub Stars](https://img.shields.io/github/stars/cloudposse/github-authorized-keys.svg)](https://github.com/cloudposse/github-authorized-keys/stargazers)\n[![GitHub Issues](https://img.shields.io/github/issues/cloudposse/github-authorized-keys.svg)](https://github.com/cloudposse/github-authorized-keys/issues)\n[![Contributions Welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg)](https://github.com/cloudposse/github-authorized-keys/pulls)\n[![License](https://img.shields.io/badge/license-APACHE%202.0%20-brightgreen.svg)](https://github.com/cloudposse/github-authorized-keys/blob/master/LICENSE)\n\n----\n\n## Screenshots\n\n**Administrators**\n\n* Automatically provision new users to production servers simply by adding them to a designatd GitHub team (e.g. `ssh`).\n  ![Demo](docs/github-team-demo.png)\n* No need to keep `authorized_keys` up to date because keys are pulled directly from github.com API and *optionally* cached in etcd\n* Immediately revoke SSH access to servers by evicting users from the GitHub team\n* Easy to deploy\n\n**End Users**\n\n* Self-administer public SSH keys via the [GitHub account settings](https://github.com/settings/keys).\n  ![Demo](docs/github-keys-demo.png)\n* No need to manage multiple SSH keys\n\n## Architecture\n\nThis tool consists of three parts:\n\n1. User Account / Authorized Keys provisioner which polls [GitHub API for users](https://developer.github.com/v3/users/keys/) that correspond to a\n   given GitHub Organization \u0026 Team using a [personal access token](https://github.com/settings/tokens). It's responsible for adding or removing users\n   from the system. All commands are templatized to allow it to run on multiple distributions.\n2. Simple read-only REST API that provides public keys for users, which is used by the `AuthorizedKeysCommand` in the `sshd_config`; this allows you\n   to expose the service internally without compromising your Github Token. The public SSH access keys are *optionally* cached in Etcd for performance\n   and reliability.\n3. An `AuthorizedKeysCommand` [script](contrib/authorized-keys) that will `curl` the REST API for a user's public keys.\n\n## Getting Started\n\nBy far, the easiest way to get up and running is by using the ready-made docker container. The only dependency\nis [Docker](https://docs.docker.com/engine/installation) itself. We also provide\na [Kubernetes Helm Chart](https://github.com/cloudposse/charts/tree/master/incubator/github-authorized-keys). If you run [CoreOS](docs/coreos.md) or\nuse `systemd`, there's a [sample unit file](contrib/github-authorized-keys.service).\n\nCloud Posse provides a public image [cloudposse/github-authorized-keys](https://hub.docker.com/r/cloudposse/github-authorized-keys/) that is built\nusing [TravisCI](.travis.yml) or you can build your own from source.\n\n```\ndocker build -t cloudposse/github-authorized-keys .\n```\n\n### Running GitHub Authorized Keys\n\nAll arguments can be passed both as environment variables or command-line arguments, or even mix-and-match them to suit your tastes.\n\nAvailable configuration options:\n\n| **Environment Variable** | **Argument**            | **Description**                                   | **Default**              |\n|--------------------------|-------------------------|---------------------------------------------------|--------------------------|\n| `GITHUB_API_TOKEN`       | `--github-api-token`    | GitHub API Token (read-only)                      |                          |\n| `GITHUB_ORGANIZATION`    | `--github-organization` | GitHub Organization Containing Team               |                          |\n| `GITHUB_TEAM`            | `--github-team`         | GitHub Team for Membership to Grant SSH Access    |                          |\n| `GITHUB_TEAM_ID`         | `--github-team-id`      | GitHub Team ID for Membership to Grant SSH Access |                          |\n| `SYNC_USERS_GID`         | `--sync-users-gid`      | Default Group ID (aka `gid`) of users             |                          |\n| `SYNC_USERS_GROUPS`      | `--sync-users-groups`   | Default \"Extra\" Groups                            |                          |\n| `SYNC_USERS_SHELL`       | `--sync-users-shell`    | Default Login Shell                               | `/bin/bash`              |\n| `SYNC_USERS_ROOT`        | `--sync-users-root`     | `chroot` path for user commands                   | `/`                      |\n| `SYNC_USERS_INTERVAL`    | `--sync-users-interval` | Interval used to update user accounts             | `300`                    |\n| `ETCD_ENDPOINT`          | `--etcd-endpoint`       | Etcd endpoint used for caching public keys        |                          |\n| `ETCD_TTL`               | `--etcd-ttl`            | Duration (in seconds) to cache public keys        | `86400`                  |\n| `ETCD_PREFIX`            | `--etcd-prefix`         | Prefix for public keys stored in etcd             | `github-authorized-keys` |\n| `LISTEN`                 | `--listen`              | Bind address used for REST API                    | `:301`                   |\n| `INTEGRATE_SSH`          | `--integrate-ssh`       | Flag to automatically configure SSH               | `false`                  |\n| `LOG_LEVEL`              | `--log-level`           | Ccontrol the logging verbosity.                   | `info`                   |\n\n## Quick Start\n\nWe recommend that you specify all parameters as environment variables. If using `docker`, pass the [environment file](contrib/env) to the container\nusing the `--env-file` argument.\n\nObtain the GitHub API Token (aka Personal Access Token) [here](https://github.com/settings/tokens). Click \"Generate new token\" and select `read:org`.\nThat's it!\n\n![Personal Access Token Permissions](docs/personal-access-token.png)\n\nFor example, [`/etc/github-authorized-keys`](contrib/env), might look like this:\n\n```\nGITHUB_API_TOKEN={token}\nGITHUB_ORGANIZATION={organization}\nGITHUB_TEAM=ssh\nSYNC_USERS_GID=500\nSYNC_USERS_GROUPS=sudo\nSYNC_USERS_SHELL=/bin/bash\nSYNC_USERS_ROOT=/host\nSYNC_USERS_INTERVAL=300\nETCD_ENDPOINT=http://localhost:2739\nETCD_TTL=86400\nETCD_PREFIX=github-authorized-keys\nLISTEN=:301\nINTEGRATE_SSH=true\n```\n\nThen you could start it like this:\n\n```\ndocker run \\\n  --volume /:/host \\\n  --expose \"127.0.0.1:301:301\" \\\n  --env-file /etc/github-authorized-keys \\\n     cloudposse/github-authorized-keys:latest\n```\n\n**IMPORTANT** Remember to expose the REST API so you can retrieve user's public keys. Only public keys belonging to users found in the GitHub team\nwill be returned.\n\n**Note:** depending on your OS distribution, you might need to tweak the command templates. Keep reading for details.\n\n## Usage Examples\n\n### Automatically Configure SSH\n\nTo leverage the `github-authorized-keys` API, we need to make a small tweak to the `sshd_config`.\n\nThis can be done automatically by passing the `--integrate-ssh` flag (or setting `INTEGRATE_SSH=true`)\n\nAfter modifying the `sshd_config`, it's necessary to restart the SSH daemon. This happens automatically by calling the `SSH_RESTART_TPL` command.\nSince this differs depending on the OS distribution, you can change the default behavior by setting the `SSH_RESTART_TPL` environment variable (\ndefault: `/usr/sbin/service ssh force-reload`). Similarly, you might need to tweak the `AUTHORIZED_KEYS_COMMAND_TPL` environment variable to something\ncompatible with your OS.\n\n### Manually Configure SSH\n\nIf you wish to manually configure your `sshd_config`, here's all you need to do:\n\n```\nAuthorizedKeysCommand /usr/bin/authorized-keys\nAuthorizedKeysCommandUser root\n```\n\nThen install a [wrapper script](contrib/authorized-keys) to `/usr/bin/authorized-keys`.\n\n**Note**: this command requires `curl` to access the REST API in order to fetch authorized keys\n\n### Etcd Fallback Cache\n\nThe REST API supports Etcd as cache for public keys. This mitigates any connectivity problems with GitHub's API. By default, the caching is disabled.\n\n### Command Templates\n\nDue to the vast differences between OS commands, the defaults provided might not work for you flavor of Linux.\n\nBelow are some of the settings which can be tweaked.\n\n| Environment Variable          | **Description**                                                                 | **Default**                                                                        \n|-------------------------------|---------------------------------------------------------------------------------|------------------------------------------------------------------------------------\n| `LINUX_USER_ADD_TPL`          | Command used to add a user to the system when no default group supplied.        | `adduser {username} --disabled-password --force-badname --shell {shell}`           \n| `LINUX_USER_ADD_WITH_GID_TPL` | Command used to add a user to the system when a default primary gid supplied  . | `adduser {username} --disabled-password --force-badname --shell {shell} --gid {gid |group}`\n| `LINUX_USER_ADD_TO_GROUP_TPL` | Command used to add the user to secondary groups                                | `adduser {username} {group}`                                                       \n| `LINUX_USER_DEL_TPL`          | Command used to delete a user from the system when removed the the team         | `deluser {username}`                                                               \n| `SSH_RESTART_TPL`             | Command used to restart SSH when `INTEGRATE_SSH=true`                           | `/usr/sbin/service ssh force-reload`                                               \n| `AUTHORIZED_KEYS_COMMAND_TPL` | Command used to fetch a user's `authorized_keys` from REST API                  | `/usr/bin/github-authorized-keys`                                                  \n\nThe values in `{braces}` are macros that will be automatically substituted at run-time.\n\n| **Macro**    | **Description**           |\n|--------------|---------------------------|\n| `{username}` | User's login name         |\n| `{shell}`    | User's login shell        |\n| `{group}`    | User's primary group name |\n| `{gid}`      | User's primary group id   |\n\n## Help\n\n**Got a question?**\n\nFile a GitHub [issue](https://github.com/cloudposse/github-authorized-keys/issues), send us an [email](mailto:hello@cloudposse.com) or reach out to us\non [Gitter](https://gitter.im/cloudposse/).\n\n## Contributing\n\n### Bug Reports \u0026 Feature Requests\n\nPlease use the [issue tracker](https://github.com/cloudposse/github-authorized-keys/issues) to report any bugs or file feature requests.\n\n### Developing\n\nIf you are interested in being a contributor and want to get involved in developing GitHub Authorized Keys, we would love to hear from you! Shoot us\nan [email](mailto:hello@cloudposse.com).\n\nIn general, PRs are welcome. We follow the typical \"fork-and-pull\" Git workflow.\n\n1. **Fork** the repo on GitHub\n2. **Clone** the project to your own machine\n3. **Commit** changes to your own branch\n4. **Push** your work back up to your fork\n5. Submit a **Pull request** so that we can review your changes\n\n**NOTE:** Be sure to merge the latest from \"upstream\" before making a pull request!\n\nHere's how to get started...\n\n1. `git clone https://github.com/cloudposse/github-authorized-keys.git` to pull down the repository\n2. `make init` to initialize the [`build-harness`](https://github.com/cloudposse/build-harness/)\n3. Review the [documentation](docs/) on compiling\n\n## License\n\n[APACHE 2.0](LICENSE) © 2016-2017 [Cloud Posse, LLC](https://cloudposse.com)\n\n    Licensed to the Apache Software Foundation (ASF) under one\n    or more contributor license agreements.  See the NOTICE file\n    distributed with this work for additional information\n    regarding copyright ownership.  The ASF licenses this file\n    to you under the Apache License, Version 2.0 (the\n    \"License\"); you may not use this file except in compliance\n    with the License.  You may obtain a copy of the License at\n     \n      http://www.apache.org/licenses/LICENSE-2.0\n\n    Unless required by applicable law or agreed to in writing,\n    software distributed under the License is distributed on an\n    \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY\n    KIND, either express or implied.  See the License for the\n    specific language governing permissions and limitations\n    under the License.\n\n## About\n\nGitHub Authorized Keys is maintained and funded by [Cloud Posse, LLC][website]. Like it? Please let us know at \u003chello@cloudposse.com\u003e\n\nWe love [Open Source Software](https://github.com/cloudposse/)!\n\nSee [our other projects][community] or [hire us][hire] to help build your next cloud-platform.\n\n[website]: http://cloudposse.com/\n\n[community]: https://github.com/cloudposse/\n\n[hire]: http://cloudposse.com/contact/\n\n### Contributors\n\n| [![Erik Osterman][erik_img]][erik_web]\u003cbr/\u003e[Erik Osterman][erik_web] | [![Igor Rodionov][igor_img]][igor_web]\u003cbr/\u003e[Igor Rodionov][igor_web] |\n|----------------------------------------------------------------------|----------------------------------------------------------------------|\n\n[erik_img]: http://s.gravatar.com/avatar/88c480d4f73b813904e00a5695a454cb?s=144\n\n[erik_web]: https://github.com/osterman/\n\n[igor_img]: http://s.gravatar.com/avatar/bc70834d32ed4517568a1feb0b9be7e2?s=144\n\n[igor_web]: https://github.com/goruha/\n\n\n","funding_links":["https://github.com/sponsors/cloudposse"],"categories":["Go"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudposse%2Fgithub-authorized-keys","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudposse%2Fgithub-authorized-keys","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudposse%2Fgithub-authorized-keys/lists"}