Circleci Github Integration
Originally
ADR-0005-CIRCLECI-GITHUB-INTEGRATION (v6) · Source on Confluence ↗Title
Context and Problem Statement
Continious automation and self-service integrations will improve speed of the development process and product delivery to the user, as a result it will decrease each delivery cost.
Development process will require integrating several repositories together for various use case to prevent code duplication across different repositories, to synchronize pipelines or to setup versioning.
By default single repository is being created with a single read-only ssh key from corresponding CircleCi project.
We identified 3 main use cases to address a need of automation for integrating repositories with pipelines between each other:
- As a developer, I want to be able in one CircleCi pipeline to pull other git repositories, so that I don’t need to duplicate the same code for dependencies across multiple repositories, but handle one code base in one place.
- As a developer I want to be able to pull/push changes and/or open PRs in repository from CircleCi pipeline, so I can implement automated versioning and some file changes in the repo.
- As a developer, I want to be able in CircleCi pipeline to push changes in different repository in protected branch, so I can have a repository (repo A) with proto files to auto-generate a code in different languages and commit changes in protected branch for destination repo (repo B). That repo (repo B) will be used as a dependency in application level project (repo C). Auto-generated code (repo B) doesn’t require testing because it should be done on base repo level (repo A).
Considered options
Details for each option provided below.
Read-only dependency
- One-to-one with SSH key
- One-to-many with GitHub token
Write dependency:
- One-to-one with SSH key
- One-to-many with GitHub token
Write dependency in protected branch:
- Custom one-to-many with GitHub token
- One-to-one with SSH key and ability to lower branch protection
Decision driver
- Scalability
- Automation
- Self-service
- Usability
- Security
Decision Outcome
One-to-one with SSH key
This will allow secure and iterative approach moving forward to isolate pipelines between each other and reduce a need of manual token rotation and management on Github, as there is no way for automating it.
Consequences
If individual SSH key is exposed or leaked, it isn’t containing any data/context/metadat inside. It will be hard to guess or identify which access the key provides.
In means of Github tokens, if the variable is named with key information that lead to the Github, then it is pretty easy to look for the API documentation and try to run some requests, list all accessible repository, try some actions on them read/write/delete.
As SSH key will be always attached to a single Github repo, the security risk will be always low, but SSH key doesn’t provide ability to open PRs, but only to push git commits in repository.
The plan will include 3 stages of implementing all coevered use-cases and at first it will be half-manual way, but without any dependency on PE team.
V1 - Will require from Engineers to configure each CI to Github connection based on documentation
PE dependency/effort: Low
Read-only dependency :heavy_check_mark:
Read-write dependency :heavy_check_mark:
Write in protected branch isn’t covered ❌
End-to-end automation via self-service ❌
- PE: to document creation of SSH key pair.
- PE: to document self-service approach of adding public key on Github repository using pe-github-automation.
- Engineers: to generate keys on local per repo.
- Engineers: to add private key on CircleCi manually per repo.
- Engineers: to add public key on Github with terraform in pe-github-automation per repo.
V2 - Will add ability to tune branch protection on individual repositories
PE dependency/effort: Medium
Write in protected branch isn’t covered :heavy_check_mark:
End-to-end automation via self-service ❌
- PE: to add flag in github terraform module to modify branch protection to only allow commits into active branch if they are coming from specific username of service account (
devops@droneup.com). - PE: to create a Github token under
devops@droneup.comto enable committing in protected branch, save in CircleCi context. This token will be modified to have read/write access only to limited amount of repos, configuration will be changed manually when required. - PE: to create an example of code snippet to use in CircleCi pipeline on how to clone repo with token under context and how to commit changes in protected branch.
- Engineers: to use flag only on repos with generated code to enable commits in trunk done by CircleCi pipeline.
- Engineers: to customize pipeline if it is required to commit code in protected branch in another repo.
V3 - Develop a way to configure additional SSH keys on CircleCi with automation
PE dependency/effort: High
End-to-end automation via self-service
- PE: to investigate options to generate SSH keys for CircleCi and use them inside of pipeline with some alternative way to manual suggestion from CircleCi (for example, CircleCi sercret with private key in CircleCi project variables).
- PE: to add an option in terraform github module to setup keys between different repositories (one-to-one with ability for one pipeline to call/checkout different repositories).
- PE: to add an option inside of basic PE CircleCi orb to utilize the pre-generated SSH key for accessing other repositories.
- Engineers: to use one place to configure relation between different repositories (pe-github-automation).
Pros and Cons of the Options
Use case 1: Read-only dependency:
One-to-one with SSH key (1 integration will provide access from 1 CircleCi pipeline to read from 1 Github repository):
- Effort: High (manual for each connection).
- Security risk: Low.
- Rotation effort: Low (Read access in one repo).
One-to-many with GitHub token (1 integration will provide access from 1 CircleCi pipeline to read from any Github repository):
- Effort: Low.
- Security risk: Medium (Read access in all - repositories under Github org).
- Rotation effort: Low (Rare manual).
Use case 2: Write dependency
One-to-one with SSH key (1 integration will provide access from 1 CircleCi pipeline to write (push git commits) in 1 Github repository):
- Effort: High (manual for each connection).
- Security risk: Low.
- Rotation effort: Low.
One-to-many with GitHub token (1 integration will provide access from 1 CircleCi pipeline to write (create commits/open PRs) in any Github repository):
- Effort: Low.
- Security risk: High (Write access in all repositories under Github org).
- Rotation effort: Low (Rare manual).
Use case 3: Write dependency in protected branch
Custom one-to-many with GitHub token (1 integration will provide access from 1 CircleCi pipeline to modify settings and write in many Github repository, not any):
- Effort: Medium .
- Security risk: Medium(Read and write access in some list of repositories repositories under Github org).
- Rotation effort: Low.
One-to-one with SSH key and ability to lower branch protection (1 integration will provide access from 1 CircleCi pipeline to write (push git commits) in protected branch in 1 Github repository):
- Effort: High (manual for each connection).
- Security risk: Medium (allows to commit changes in trunk branch for individual repositories).
- Rotation effort: Low.