vault-plugin-secrets-github

command module
v1.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 14, 2021 License: Apache-2.0 Imports: 5 Imported by: 0

README

[[https://github.com/martinbaillie/vault-plugin-secrets-github/actions][https://github.com/martinbaillie/vault-plugin-secrets-github/workflows/build/badge.svg]]
[[https://codecov.io/gh/martinbaillie/vault-plugin-secrets-github][https://codecov.io/gh/martinbaillie/vault-plugin-secrets-github/branch/master/graph/badge.svg]]
[[https://godoc.org/github.com/martinbaillie/vault-plugin-secrets-github][https://godoc.org/github.com/martinbaillie/vault-plugin-secrets-github?status.svg]]
[[https://goreportcard.com/report/github.com/martinbaillie/vault-plugin-secrets-github][https://goreportcard.com/badge/github.com/martinbaillie/vault-plugin-secrets-github?status.svg]]
[[https://github.com/martinbaillie/vault-plugin-secrets-github/releases/latest][https://img.shields.io/github/release/martinbaillie/vault-plugin-secrets-github.svg]]

* Vault Plugin Secrets GitHub                                :TOC_2_gh:noexport:
- [[#about][About]]
  - [[#why][Why?]]
  - [[#what][What?]]
  - [[#how][How?]]
- [[#installation][Installation]]
  - [[#from-release][From release]]
  - [[#from-source][From source]]
  - [[#setup-github][Setup (GitHub)]]
  - [[#setup-vault][Setup (Vault)]]
- [[#api][API]]
  - [[#token][Token]]
  - [[#permission-sets][Permission sets]]
  - [[#config][Config]]
  - [[#metrics][Metrics]]
  - [[#info][Info]]
- [[#development][Development]]
  - [[#tests][Tests]]
- [[#security][Security]]

* About
Are you using HashiCorp Vault and GitHub in your organisation? Do you want
ephemeral, finely-scoped GitHub tokens? If so, this plugin might be for you.

#+begin_quote
UPDATE: The plugin was recently demoed at HashiCorp's [[https://www.youtube.com/watch?v=JuzBolDyGdg&t=17308s][Hashitalks 2021]].
#+end_quote

** Why?
Performing automation against GitHub APIs often neccessitates the creation of
[[https://help.github.com/en/github/extending-github/git-automation-with-oauth-tokens][OAuth Tokens]]. These tokens are tied to a user account, have /very/
[[https://developer.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps/#available-scopes][coarsely-scoped permissions]] and do not expire.

As an organisation owner this likely means your automation-savvy users have
created personal access tokens with powerful permissions which are being neither
rotated nor deleted.

You will also commonly have wasted at least one of your GitHub seats on a
[[https://help.github.com/en/github/getting-started-with-github/types-of-github-accounts#personal-user-accounts][robot/machine user]] for CI/CD purposes. These users share a similar access token
and SSH key story as your human users do, and additonally need their credentials
managed and rotated for them (arguably made more awkward when authenticating
through an IdP).

[[https://developer.github.com/apps/building-github-apps/][GitHub Apps]] offer a better approach to this automation problem:

- They do not consume a seat (license) nor need credential management.
- They have /much/ finer-grained [[https://developer.github.com/v3/apps/permissions/][permissions]] available to the access tokens.
- The tokens they issue expire after one hour.

However, GitHub Apps require the management of at least one private key which is
needed to mint the JWTs used for the [[https://developer.github.com/apps/building-github-apps/authenticating-with-github-apps/#authenticating-as-an-installation][App installation authentication]] token
request flow.

** What?
This plugin allows you to take advantage of your existing Vault deployment's
durable storage backend to protect the GitHub App private key, and your enabled
Vault authN/Z mechanisms and highly-available API to perform the GitHub App
token request flow on behalf of your users.

** How?
The Vault plugin acts as an intermediary for a GitHub App that you install into
your organisation:

#+ATTR_ORG: :width 1024
#+CAPTION: Logical Architecture
[[file:vault_github_plugin.png]]

Users login using your existing Vault auth backend(s) and, Vault RBAC
permitting, can request GitHub tokens from the plugin. The plugin, in turn,
authenticates with the GitHub App and requests a token on behalf of the user.
This flow is better explained in the sequence diagram below:

#+CAPTION: Sequence Diagram
[[https://mermaid-js.github.io/mermaid-live-editor/#/view/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gICAgcGFydGljaXBhbnQgViBhcyBWYXVsdFxuICAgIHBhcnRpY2lwYW50IEcgYXMgR2l0SHViXG4gICAgTm90ZSBvdmVyIFU6IEh1bWFuLCBDSS9DRCBhZ2VudCBldGMuXG4gICAgVS0+PlY6IFBPU1QgeW91ci52YXVsdC5vcmcvdjEvYXV0aFxuICAgIGFjdGl2YXRlIFZcbiAgICBOb3RlIG92ZXIgVjogU1NPLCBBRCwgQ2xvdWQgSUFNIGV0Yy5cbiAgICBWLS0+PlU6IE9LXG4gICAgZGVhY3RpdmF0ZSBWXG4gICAgTm90ZSByaWdodCBvZiBVOiBSZXF1ZXN0IGEgR2l0SHViIHRva2VuXG4gICAgYWx0XG4gICAgVS0+PlY6IFBPU1QgeW91ci52YXVsdC5vcmcvdjEvZ2l0aHViL3Rva2VuXG4gICAgZWxzZSByZXBvczogWzEyMyw0NTZdLCBwZXJtczogXCJpc3N1ZXM6d3JpdGVcIlxuICAgIFUtPj5WOiBQT1NUIHlvdXIudmF1bHQub3JnL3YxL2dpdGh1Yi90b2tlblxuICAgIGVuZFxuICAgIGFjdGl2YXRlIFZcbiAgICBOb3RlIG92ZXIgVjogTWludCBKV1QgdXNpbmcgUHJpdmF0ZSBLZXlcbiAgICBWLT4+VjogR2l0SHViIEpXVCAoZXhwOiAxMG0pXG4gICAgVi0+Pkc6IFBPU1QgYXBpLmdpdGh1Yi5jb20vLi4uL2FjY2Vzc190b2tlbnNcbiAgICBHLS0+PlY6IHRva2VuOiBbIFwidjEuMTIzNDU2Nzg5Li4uXCIgZXhwOiBcIjFoXCIgXVxuICAgIFYtPj5WOiBSZWNvcmQgbWV0cmljcywgbG9nc1xuICAgIFYtLT4+VTogWyB0b2tlbjogXCJ2MS4xMjM0NTY3ODkuLi5cIiBleHA6IFwiMWhcIiBdXG4gICAgZGVhY3RpdmF0ZSBWXG4gICAgTm90ZSBvdmVyIFU6IFVzZSBhY2Nlc3MgdG9rZW4gb24gR2l0SHViXG4gICAgYWx0IE9wZXJhdGUgb24gcmVwb3N0b3JpZXMgYWNjZXNzIHRva2VuIGhhcyBwZXJtaXNzaW9ucyBvblxuICAgIFUtPj5HOiAkIGdpdCBjbG9uZSBodHRwczovL3gtYWNjZXNzLXRva2VuOnYxLjEyMzQ1Njc4OS4uLkBnaXRodWIuY29tL29yZy9yZXBvLmdpdFxuICAgIGVsc2UgUGVyZm9ybSBBUEkgcmVxdWVzdHMgYWdhaW5zdCByZXNvdXJjZXMgYWNjZXNzIHRva2VuIGhhcyBwZXJtaXNzaW9ucyBvblxuICAgIFUtPj5HOiAkIGN1cmwgLUggXCJBdXRob3JpemF0aW9uOiBCZWFyZXIgdjEuMTIzNDU2Nzg5Li4uXCIgaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXNvdXJjZVxuICAgIGVuZCIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0Iiwic2VxdWVuY2UiOnsibWlycm9yQWN0b3JzIjpmYWxzZSwiYWN0b3JNYXJnaW4iOjEyMCwibm90ZU1hcmdpbiI6MTAsIm1lc3NhZ2VNYXJnaW4iOjMwLCJib3hUZXh0TWFyZ2luIjoxLCJoZWlnaHQiOjMwLCJ3aWR0aCI6MjAwfX19][https://mermaid.ink/img/eyJjb2RlIjoic2VxdWVuY2VEaWFncmFtXG4gICAgcGFydGljaXBhbnQgVSBhcyBVc2VyXG4gICAgcGFydGljaXBhbnQgViBhcyBWYXVsdFxuICAgIHBhcnRpY2lwYW50IEcgYXMgR2l0SHViXG4gICAgTm90ZSBvdmVyIFU6IEh1bWFuLCBDSS9DRCBhZ2VudCBldGMuXG4gICAgVS0+PlY6IFBPU1QgeW91ci52YXVsdC5vcmcvdjEvYXV0aFxuICAgIGFjdGl2YXRlIFZcbiAgICBOb3RlIG92ZXIgVjogU1NPLCBBRCwgQ2xvdWQgSUFNIGV0Yy5cbiAgICBWLS0+PlU6IE9LXG4gICAgZGVhY3RpdmF0ZSBWXG4gICAgTm90ZSByaWdodCBvZiBVOiBSZXF1ZXN0IGEgR2l0SHViIHRva2VuXG4gICAgYWx0XG4gICAgVS0+PlY6IFBPU1QgeW91ci52YXVsdC5vcmcvdjEvZ2l0aHViL3Rva2VuXG4gICAgZWxzZSByZXBvczogWzEyMyw0NTZdLCBwZXJtczogXCJpc3N1ZXM6d3JpdGVcIlxuICAgIFUtPj5WOiBQT1NUIHlvdXIudmF1bHQub3JnL3YxL2dpdGh1Yi90b2tlblxuICAgIGVuZFxuICAgIGFjdGl2YXRlIFZcbiAgICBOb3RlIG92ZXIgVjogTWludCBKV1QgdXNpbmcgUHJpdmF0ZSBLZXlcbiAgICBWLT4+VjogR2l0SHViIEpXVCAoZXhwOiAxMG0pXG4gICAgVi0+Pkc6IFBPU1QgYXBpLmdpdGh1Yi5jb20vLi4uL2FjY2Vzc190b2tlbnNcbiAgICBHLS0+PlY6IHRva2VuOiBbIFwidjEuMTIzNDU2Nzg5Li4uXCIgZXhwOiBcIjFoXCIgXVxuICAgIFYtPj5WOiBSZWNvcmQgbWV0cmljcywgbG9nc1xuICAgIFYtLT4+VTogWyB0b2tlbjogXCJ2MS4xMjM0NTY3ODkuLi5cIiBleHA6IFwiMWhcIiBdXG4gICAgZGVhY3RpdmF0ZSBWXG4gICAgTm90ZSBvdmVyIFU6IFVzZSBhY2Nlc3MgdG9rZW4gb24gR2l0SHViXG4gICAgYWx0IE9wZXJhdGUgb24gcmVwb3N0b3JpZXMgYWNjZXNzIHRva2VuIGhhcyBwZXJtaXNzaW9ucyBvblxuICAgIFUtPj5HOiAkIGdpdCBjbG9uZSBodHRwczovL3gtYWNjZXNzLXRva2VuOnYxLjEyMzQ1Njc4OS4uLkBnaXRodWIuY29tL29yZy9yZXBvLmdpdFxuICAgIGVsc2UgUGVyZm9ybSBBUEkgcmVxdWVzdHMgYWdhaW5zdCByZXNvdXJjZXMgYWNjZXNzIHRva2VuIGhhcyBwZXJtaXNzaW9ucyBvblxuICAgIFUtPj5HOiAkIGN1cmwgLUggXCJBdXRob3JpemF0aW9uOiBCZWFyZXIgdjEuMTIzNDU2Nzg5Li4uXCIgaHR0cHM6Ly9hcGkuZ2l0aHViLmNvbS9yZXNvdXJjZVxuICAgIGVuZCIsIm1lcm1haWQiOnsidGhlbWUiOiJkZWZhdWx0Iiwic2VxdWVuY2UiOnsibWlycm9yQWN0b3JzIjpmYWxzZSwiYWN0b3JNYXJnaW4iOjEyMCwibm90ZU1hcmdpbiI6MTAsIm1lc3NhZ2VNYXJnaW4iOjMwLCJib3hUZXh0TWFyZ2luIjoxLCJoZWlnaHQiOjMwLCJ3aWR0aCI6MjAwfX19?nothing.svg]]

#+BEGIN_COMMENT Mermaid source
sequenceDiagram
    participant U as User
    participant V as Vault
    participant G as GitHub
    Note over U: Human, CI/CD agent etc.
    U->>V: POST your.vault.org/v1/auth
    activate V
    Note over V: SSO, AD, Cloud IAM etc.
    V-->>U: OK
    deactivate V
    Note right of U: Request a GitHub token
    alt
    U->>V: POST your.vault.org/v1/github/token
    else repos: [123,456], perms: "issues:write"
    U->>V: POST your.vault.org/v1/github/token
    end
    activate V
    Note over V: Mint JWT using Private Key
    V->>V: GitHub JWT (exp: 10m)
    V->>G: POST api.github.com/.../access_tokens
    G-->>V: token: [ "v1.123456789..." exp: "1h" ]
    V->>V: Record metrics, logs
    V-->>U: [ token: "v1.123456789..." exp: "1h" ]
    deactivate V
    Note over U: Use access token on GitHub
    alt Operate on repostories access token has permissions on
    U->>G: $ git clone https://x-access-token:v1.123456789...@github.com/org/repo.git
    else Perform API requests against resources access token has permissions on
    U->>G: $ curl -H "Authorization: Bearer v1.123456789..." https://api.github.com/resource
    end
#+END_COMMENT
#+BEGIN_COMMENT Mermaid style
{
  "theme": "default",
  "sequence": {
  "mirrorActors": false,
  "actorMargin": 120,
  "noteMargin": 10,
  "messageMargin": 30,
  "boxTextMargin": 1,
  "height": 30,
  "width": 200
  }
}
#+END_COMMENT

* Installation
To begin plugin installation, either download a [[./releases][release]] or build
from source for your chosen OS and architecture.

** From release
Always download the latest stable release from the [[./releases][releases]] section.

*** Verify

You can and should verify the authenticity and integrity of the plugin you
downloaded. All released binaries are hashed and the resulting sums are signed
by my GPG key.

#+BEGIN_SRC shell
# Import my key.
curl -sS https://github.com/martinbaillie.gpg | gpg --import -

# Verify the authenticity.
gpg --verify SHA256SUMS.sig SHA256SUMS

# Verify the integrity.
shasum -a 256 -c SHA256SUMS
#+END_SRC

** From source
#+BEGIN_QUOTE
NOTE: You will need a [[https://golang.org/dl/][Go 1.13+ toolchain]] to build this plugin from source.
#+END_QUOTE

1. Either download the source zip/tar.gz of the latest release from the [[./releases][releases]]
   section and uncompress, or shallow clone to the target release tag as in
   below:

    #+BEGIN_SRC shell
    git clone --depth 1 -b <target_release_tag> \
        https://github.com/martinbaillie/vault-plugin-secrets-github.git
    #+END_SRC

2. Build for your target OS and architecture. The [[./Makefile][Makefile]] has auto-generated
   targets for each supported combination (see: =make help=). Examples:

    #+BEGIN_SRC shell
    # Build for Linux/AMD64.
    make vault-plugin-secrets-github-linux-amd64

    # Build for OpenBSD/ARM.
    make vault-plugin-secrets-github-openbsd-arm

    # Build every supported OS and architecture combination.
    make build
    #+END_SRC

** Setup (GitHub)
#+BEGIN_QUOTE
NOTE: You will need access to admin of your GitHub or GitHub Enterprise
organisation to continue with the one-time setup. You can of course use this
plugin on your personal account if so desired.
#+END_QUOTE

1. Sign in as an org admin and begin creating a new [[https://github.com/settings/apps/new][GitHub App.]]

2. Choose any unique name, and homepage / webhook URLs (these can be anything;
   they are not required by the plugin).
   #+BEGIN_QUOTE
    NOTE: You may wish to take advantage of having GitHub call a webhook URL you own each
    time the App is used for auditing purposes.
    #+END_QUOTE

3. Carefully choose the permissions the App will have access to. This is the
   superset of permissions. You will have the option of further restricting
   access to all or some repositories when you install an instance of the App,
   and users of this plugin will be able to even further restrict access in
   their individual token requests.

4. Decide if you want the app to be installable to other accounts. Usually
   you just want the one you are signed into.

5. Create the App. On the next screen GitHub will prompt you to create a *Private
   Key*. Do so, and save it somewhere safe (this is the key that will be
   ultimately lodged into the plugin configuration).

6. Note the *App ID* at the top of this page as well.
    #+BEGIN_QUOTE
    NOTE: Get the App ID anytime: Settings > Developer > settings > GitHub App >
    About item.
    #+END_QUOTE

7. Click Install App from the LHS. You will be taken to the account installation
   pages where you can confirm the app was installed.

8. (OPTIONAL as of v1.3.0) Note the *Installation ID* from the URL of this page (usually:
   https://github.com/settings/installations/<installation id>) if you wish to
   configure using the installation ID directly.
    #+BEGIN_QUOTE
    NOTE: Get the Installation ID anytime: Settings > Developer > settings >
    GitHub Apps > Advanced > Payload in Request tab.
    #+END_QUOTE

** Setup (Vault)
Using the information noted from the previous step (Private Key, App ID and
optionally the Installation ID), you are ready to move on to setting up the
Vault plugin.

1. Move the desired plugin binary into your Vault's configured
   =plugin_directory=.

    #+BEGIN_SRC shell
    mv vault-plugin-secrets-github-<os>-<arch> <plugin_directory>/vault-plugin-secrets-github
    #+END_SRC

2. (OPTIONAL) Allow [[https://linux.die.net/man/2/mlock][ =mlock()= ]] capabilities for the plugin binary. Memory locking
   is available to most UNIX-like OSes; the example below is for Linux.

    #+BEGIN_SRC shell
    setcap cap_ipc_lock=+ep <plugin_directory>/vault-plugin-secrets-github
    #+END_SRC

3. (OPTIONAL) Calculate the SHA256 sum of the plugin and register it in Vault's
   plugin catalog. If you are downloading the pre-compiled binary, it is highly
   recommended that you use the published SHA256SUMS file.

    #+BEGIN_QUOTE
    NOTE: The rest of these commands assume you have a valid VAULT_TOKEN and
    VAULT_API environment variables.
    #+END_QUOTE

    #+BEGIN_SRC shell
    # If using a pre-compiled binary:
    SHA256SUM=$(grep <downloaded_binary> SHA256SUMS | cut -d' ' -f1)
    # If building from source:
    SHA256SUM=$(shasum -a 256 <compiled_binary> | cut -d' ' -f1)

    vault write sys/plugins/catalog/secret/vault-plugin-secrets-github \
        sha_256=${SHA256SUM} command=vault-plugin-secrets-github
    #+END_SRC

4. Mount the secrets engine, choosing a prefix path (recommendation: =github=).

    #+BEGIN_SRC shell
    vault secrets enable -path=github -plugin-name=vault-plugin-secrets-github plugin
    #+END_SRC

5. Configure the plugin with the details noted from the previous section.

   #+BEGIN_SRC shell
    # Write the configuration (discovered installation ID).
    vault write /github/config app_id=<app_id> org_name=<org_name> prv_key=@<private_key_file>

    # Write the configuration (explicit installation ID).
    vault write /github/config app_id=<app_id> ins_id=<installation_id> prv_key=@<private_key_file>

    # (OPTIONAL) Confirm the configuration landed as you expected.
    vault read /github/config

    # (OPTIONAL) Test a token creation.
    vault read /github/token
   #+END_SRC

6. (OPTIONAL) Use Vault policy to constrain user capabilities on the GitHub
   endpoints. Example:

   #+BEGIN_SRC shell
# Create a restrictive policy that only permits GitHub tokens that can write
# pull requests to a single repository.
vault policy write github-only-prs -<<EOF
path "github/token" {
  capabilities = ["update"]
  required_parameters = ["permissions","repository_ids"]
  allowed_parameters = {
    "repository_ids" = ["69857131"]
    "permissions"= ["pull_requests=write"]
  }
}
EOF

# Create and login as an example user with the policy attached.
vault auth enable userpass
vault write auth/userpass/users/martin password=baillie policies="github-only-prs"
vault login -method=userpass username=martin password=baillie

# Test the efficacy of the policy.
# Successfully creates token:
vault write /github/token repository_ids=69857131 permissions=pull_requests=write
# Permission denied:
vault write -f /github/token
vault write /github/token permissions=pull_requests=write
vault write /github/token repository_ids=69857131 permissions=pull_requests=read
vault write /github/token repository_ids=69857131 permissions=metadata=read
vault write /github/token repository_ids=123 permissions=pull_requests=write
vault write /github/token repository_ids=69857131
   #+END_SRC

* API
Each plugin path is documented using Vault's own help framework. To find out
more information about any path, use =vault path-help=. For brevity, the API is
also documented below.

** Token
Instruct the plugin to create an installation access token against the configured GitHub App.

| Method | Path   | Produces         |
|--------+--------+------------------|
| GET    | /token | application/json |
| POST   | /token | application/json |
| PUT    | /token | application/json |

*** Parameters
#+begin_quote
NOTE: All parameters are optional. Omitting them results in a token that has
access to all of the repositories and permissions that the GitHub App has.

When crafting Vault policy, hyper security sensitive organisations may wish to
favour =repository_ids= (GitHub repository IDs are immutable) instead of
=repositories= (GitHub repository names are mutable).
#+end_quote

- =repositories= ([]string) — a list of the names of the repositories within the
  organisation that the installation token can access.
- =repository_ids= ([]int64) — a list of the IDs of the repositories that the
  installation token can access. See this [[https://stackoverflow.com/a/47223479][StackOverflow post]] for the quickest
  way to find a repository ID.
- =permissions= (map[string]string) — a key value map of permission names to
  their access type (read or write). See [[https://developer.github.com/v3/apps/permissions][GitHub's documentation]] on permission
  names and access types.

*** Examples
#+BEGIN_SRC shell
# Create a token with all the superset of all permissions and repositories that
# the GitHub App installation has access to.
vault read /github/token

# Create a token with read permissions on the packages and write permissions on
# the pull requests of repositories named "demo-repo" and ID 123.
vault write /github/token \
	repository_ids=123 \
	repositories=demo-repo \
	permissions=packages=read \
	permissions=pull_requests=write

# Create a token with all permissions but only on the "demo-repo" repository.
vault write /github/token repository_ids=123 repository_ids=456

# Create a token with all permissions but only on repositories 123 and 456.
vault write /github/token repository_ids=123 repository_ids=456

# Create a token with write access to pull requests using read / GET.
vault write /github/token permissions=pull_requests=write

# Create a token with read access to metadata and write access to pull requests
# on repositories "demo-repo", 123 and 456 only.
# NOTE: Uses a Vault CLI JSON heredoc to submit the complex map type.
vault write /github/token - <<EOF
{
"repositories": ["demo-repo"],
"repository_ids": [123,456],
"permissions": {"metadata": "read", "pull_requests": "write"}
}
EOF
#+END_SRC

#+BEGIN_QUOTE
NOTE: a 422 response usually indicates you have requested repositories IDs or
permissions that your GitHub App install does not have access to.
#+END_QUOTE
*** Revocation
It is possible to revoke tokens in your configured GitHub using Vault
constructs. For example:
#+begin_src shell
# Revoke an individual token with just the lease ID.
vault lease revoke <lease_id previously received from token endpoint>
# List currently active lease IDs.
vault list sys/leases/lookup/github/token
# Revoke all tokens currently leased by Vault.
vault lease revoke -prefix github/token
#+end_src

#+begin_quote
NOTE: the previous commands presume your plugin is mounted at =/github=.
#+end_quote

Alternatively, you can go directly to your GitHub with the token in hand:
#+begin_src shell
curl -H "Authorization: Bearer ${GITHUB_TOKEN}" \
	-X DELETE https://api.mygithub.com/installation/token
#+end_src

** Permission sets
Instruct the plugin to create a specific permission set.

| Method | Path                      | Produces         |
|--------+---------------------------+------------------|
| GET    | /permissionset/<name>     | application/json |
| POST   | /permissionset/<name>     | application/json |
| PUT    | /permissionset/<name>     | application/json |
| DELETE | /permissionset/<name>     | application/json |
| GET    | /permissionsets?list=true | application/json |

*** Parameters
#+begin_quote
NOTE: All parameters are optional. Omitting them results in a token that has
access to all of the repositories and permissions that the GitHub App has.

When crafting Vault policy, hyper security sensitive organisations may wish to
favour =repository_ids= (GitHub repository IDs are immutable) instead of
=repositories= (GitHub repository names are mutable).
#+end_quote

- =repositories= ([]string) — a list of the names of the repositories within the
  organisation that the installation token can access.
- =repository_ids= ([]int64) — a list of the IDs of the repositories that the
  installation token can access. See this [[https://stackoverflow.com/a/47223479][StackOverflow post]] for the quickest
  way to find a repository ID.
- =permissions= (map[string]string) — a key value map of permission names to
  their access type (read or write). See [[https://developer.github.com/v3/apps/permissions][GitHub's documentation]] on permission
  names and access types.

*** Request a token from a permission set
Similar to the [[#token][token]] flow in the previous section, you can instruct the plugin
to create an installation access token by using a permission set name. The token
returned will be constrained by that pre-configured permission set.

| Method | Path          | Produces         |
|--------+---------------+------------------|
| GET    | /token/<name> | application/json |
| POST   | /token/<name> | application/json |
| PUT    | /token/<name> | application/json |

*** Examples
#+BEGIN_SRC shell
# Configure a permission set that only allows metadata reads and PR writes
# against three repositories.
vault write /github/permissionset/demo-set - <<EOF
{
"repositories": ["demo-repo"],
"repository_ids": [123,456],
"permissions": {"metadata": "read", "pull_requests": "write"}
}
EOF
# Or
vault write /github/permissionset/demo-set \
	repositories=demo-repo \
	repository_ids=123 \
	repository_ids=456 \
	permissions=pull_requests=read \
	permissions=metadata=read

# Read the permission set configuration.
vault read /github/permissionset/demo-set

# List all permission sets.
vault list /github/permissionsets

# Create a token automatically constrained by the permission set.
vault read /github/token/demo-set

# Delete an existing permission set.
vault delete /github/token/demo-set
#+END_SRC

** Config
General CRUD operations against the configuration of the plugin.

| Method | Path    | Produces         |
|--------+---------+------------------|
| POST   | /config | application/json |
| GET    | /config | application/json |
| PUT    | /config | application/json |
| DELETE | /config | application/json |

*** Parameters
- =app_id= (int64) — the Application ID of the GitHub App.
- =ins_id= (int64) — the Installation ID of the GitHub App installation.
- =org_name= (string) — the name of the organisation with the GitHub App installation.
- =private_key= (string) — a private key configured in the GitHub App. This private key must be in PEM PKCS#1 RSAPrivateKey format. It is not returned with read requests for security reasons.
- =base_url= (string) — the base URL for API requests (defaults to the public GitHub API).

*** Examples
#+BEGIN_SRC shell
# Write the plugin configuration using the default base URL, reading the key from a file and discovering the installation ID by querying the organisation.
vault write /github/config app_id=123 org_name=my-org prv_key=@key.pem

# Write the plugin configuration using the default base URL, reading the key from a file and using an explicit installation ID.
vault write /github/config app_id=123 ins_id=456 prv_key=@key.pem

# Read the plugin configuration.
vault read /github/config

# Update the plugin configuration to a GitHub Enterprise base URL.
vault write /github/config base_url="https://api.mygithub.org"

# Delete the plugin configuration.
vault delete /github/config
#+END_SRC

** Metrics
Prometheus/OpenMetrics formatted metrics exposition.

| Method | Path     | Produces    |
|--------+----------+-------------|
| GET    | /metrics | text/plain  |

*** Metrics
In addition to standard Go metrics, the following custom metrics are exposed:
- =vault_github_token_request_duration_seconds= — a summary of token request latency and status.
- =vault_github_token_revocation_request_duration_seconds= — a summary of token revocation request latency and status.
- =vault_github_token_build_info= — a constant with useful build information.

*** Sample Dashboard
A sample dashboard is [[dashboard.json][provided]].
#+CAPTION: Sample Dashboard
[[dashboard.png][dashboard.png]]

** Info
Information about the GitHub secrets plugin, such as the plugin version, VCS
detail and where to get help.

| Method | Path  | Produces         |
|--------+-------+------------------|
| GET    | /info | application/json |

* Development
This plugin is written using modern [[https://golang.org/dl/][Go]]. You will need a Go 1.13+ toolchain and
some common userspace tools like GNU/BSD =make=, =curl= and =git=.

The [[./Makefile][Makefile]] endeavours to install more atypical tooling when needed.

#+BEGIN_QUOTE
NOTE: It is also possible to run any target inside Docker by prefixing the
target name, e.g. =make docker-test=.
#+END_QUOTE

There is also a =shell.nix= if Nix is more your bag.
** Tests
This plugin is comprehensively tested by both unit and acceptance tests. Pull
requests that do not maintain an [[https://codecov.io/gh/martinbaillie/vault-plugin-secrets-github][>90% coverage]] will *not* be accepted.

#+BEGIN_SRC shell
# Run linting and unit tests.
make test

# Run CI-grade linting and unit tests.
make test CI=true

# Run unit and acceptance tests, integrating against a local Vault and stubbed
# GitHub API.
make integration test

# Run unit and acceptance tests, integrating against a local Vault and the real
# GitHub API against your own GitHub App installation (you can also run these
# tests against a GitHub Enterprise deployment). Setting `BASE_URL` causes the
# tests to call against a real API.
# NOTE: Keep in mind this test configuration will create real tokens.
make integration test \
    BASE_URL=https://api.github.com \
    ORG_NAME=<org_name> \
    APP_ID=<app_id> \
    PRV_KEY="$(cat <path_to_app_private_key>)"
#+END_SRC

* Security
HashiCorp and GitHub take their security seriously. If you believe you have
found a security issue with either through using this plugin, do not open an
issue here. Responsibly disclose by getting in touch with [[mailto:security@hashicorp.com][HashiCorp]] or [[https://hackerone.com/github][GitHub]]
security teams respectively.

Documentation

The Go Gopher

There is no documentation for this package.

Directories

Path Synopsis
Package github manages the configuration and execution of the Vault Secrets Plugin for GitHub.
Package github manages the configuration and execution of the Vault Secrets Plugin for GitHub.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL