DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Enterprise AI Trend Report: Gain insights on ethical AI, MLOps, generative AI, large language models, and much more.

2024 Cloud survey: Share your insights on microservices, containers, K8s, CI/CD, and DevOps (+ enter a $750 raffle!) for our Trend Reports.

PostgreSQL: Learn about the open-source RDBMS' advanced capabilities, core components, common commands and functions, and general DBA tasks.

AI Automation Essentials. Check out the latest Refcard on all things AI automation, including model training, data security, and more.

Related

  • Tips To Help GitHub Admins Prepare A Company For SOC 2 And ISO 27001 Audits
  • The Elusive Quest for DevSecOps Collaboration
  • Modern DevSecOps: Benefits, Challenges, and Integrations To Achieve DevSecOps Excellence
  • Deploy a Session Recording Solution Using Ansible and Audit Your Bastion Host

Trending

  • AI and Rules for Agile Microservices in Minutes
  • Harmonizing AI: Crafting Personalized Song Suggestions
  • Deploying to Heroku With GitLab CI/CD
  • C4 PlantUML: Effortless Software Documentation
  1. DZone
  2. Software Design and Architecture
  3. Security
  4. Safe Clones With Ansible

Safe Clones With Ansible

In this tutorial, learn how to safely clone private Git repos from Ansible by using temporary GitHub deploy keys.

By 
Jan-Rudolph Bührmann user avatar
Jan-Rudolph Bührmann
·
Feb. 22, 24 · Tutorial
Like (1)
Save
Tweet
Share
4.0K Views

Join the DZone community and get the full member experience.

Join For Free

I started research for an article on how to add a honeytrap to a GitHub repo. The idea behind a honeypot weakness is that a hacker will follow through on it and make his/her presence known in the process. 

My plan was to place a GitHub personal access token in an Ansible vault protected by a weak password. Should an attacker crack the password and use the token to clone the private repository, a webhook should have triggered and mailed a notification that the honeypot repo has been cloned and the password cracked. 

Unfortunately, GitHub seems not to allow webhooks to be triggered after cloning, as is the case for some of its higher-level actions. This set me thinking that platforms as standalone systems are not designed with Dev(Sec)Ops integration in mind. DevOps engineers have to bite the bullet and always find ways to secure pipelines end-to-end. I, therefore, instead decided to investigate how to prevent code theft using tokens or private keys gained by nefarious means. 

Prevention Is Better Than Detection

It is not best practice to have secret material on hard drives thinking that root-only access is sufficient security. Any system administrator or hacker that is elevated to root can view the secret in the open. They should, rather, be kept inside Hardware Security Modules (HSMs) or a secret manager, at the very least. Furthermore, tokens and private keys should never be passed in as command line arguments since they might be written to a log file. 

A way to solve this problem is to make use of a super-secret master key to initiate proceedings and finalize using short-lived lesser keys. This is similar to the problem of sharing the first key in applied cryptography. Once the first key has been agreed upon, successive transactions can be secured using session keys. It goes beyond saying that the first key has to be stored in Hardware Security Modules, and all operations against it have to happen inside an HSM.

I decided to try out something similar when Ansible clones private Git repositories. Although I will illustrate at the hand of GitHub, I am pretty sure something similar can be set up for other Git platforms as well.

First Key

GitHub personal access tokens can be used to perform a wide range of actions on your GitHub account and its repositories. It authenticates and authorizes from both the command line and the GitHub API. It clearly can serve as the first key.  

Personal access tokens are created by clicking your avatar in the top right and selecting Settings:

Personal access tokens are created by clicking your avatar in the top right and selecting Settings

A left nav panel should appear from where you select Developer settings:

Left nav panel that appears from where you select Developer settingsThe menu for personal access tokens will display where you can create the token:

Menu for personal access tokens

I created a classic token and gave it the following scopes/permissions: repo, admin:public_key, user, and admin:gpg_key. Take care to store the token in a reputable secret manager from where it can be copied and pasted when the Ansible play asks for it when it starts. This secret manager should clear the copy buffer after a few seconds to prevent attacks utilizing attention diversion.

vars_prompt:
  - name: github_token
    prompt: "Enter your github personal access token?"
    private: true


Establishing the Session

GitHub deployment keys give access to private repositories. They can be created by an API call or from the repo's top menu by clicking on Settings:

Repo's top menu, click on settings, and deploy keys

With the personal access token as the first key, a deployment key can finish the operation as the session key. Specifically, Ansible authenticates itself using the token, creates the deployment key, authorizes the clone, and deletes it immediately afterward. 

The code from my previous post relied on adding Git URLs that contain the tokens to the Ansible vault. This has now been improved to use temporary keys as envisioned in this post. An Ansible role provided by Asif Mahmud has been amended for this as can be seen in the usual GitHub repo. The critical snippets are:

- name: Add SSH public key to GitHub account
  ansible.builtin.uri:
    url: "https://api.{{ git_server_fqdn }}/repos/{{ github_account_id }}/{{ repo }}/keys"
    validate_certs: yes
    method: POST
    force_basic_auth: true
    body:
      title: "{{ key_title }}"
      key: "{{ key_content.stdout }}"
      read_only: true
    body_format: json
    headers:
      Accept: application/vnd.github+json
      X-GitHub-Api-Version: 2022-11-28
      Authorization: "Bearer {{ github_access_token }}"
    status_code:
    - 201
    - 422
  register: create_result


The GitHub API is used to add the deploy key to the private repository. Note the use of the access token typed in at the start of play to authenticate and authorize the request.

- name: Clone the repository
  shell: |                                                                                                                                   
    GIT_SSH_COMMAND="ssh -i {{ key_path }} -v -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null" {{ git_executable }} clone git@{{ git_server_fqdn }}:{{ github_account_id }}/{{ repo }}.git {{ clone_dest }}

- name: Switch branch
  shell: "{{ git_executable }} checkout {{ branch }}"
  args:
    chdir: "{{ clone_dest }}"


The repo is cloned, followed by a switch to the required branch.

- name: Delete SSH public key
  ansible.builtin.uri:
    url: "https://api.{{ git_server_fqdn }}/repos/{{ github_account_id }}/{{ repo }}/keys/{{ create_result.json.id }}"
    validate_certs: yes
    method: DELETE
    force_basic_auth: true
    headers:
      Accept: application/vnd.github+json
      X-GitHub-Api-Version: 2022-11-28
      Authorization: "Bearer {{ github_access_token }}"
    status_code:
      - 204


Deletion of the deployment key happens directly after the clone and switch, again via the API.

Conclusion

The short life of the deployment key enhances the security of the DevOps pipeline tremendously. Only the token has to be kept secured at all times as is the case for any first key. Ideally, you should integrate Ansible with a compatible HSM platform. 

I thank Asif Mahmud for using their code to illustrate the concept of using temporary session keys when cloning private Git repositories.

GitHub Ansible (software) Clone (Java method) security DevSecOps

Opinions expressed by DZone contributors are their own.

Related

  • Tips To Help GitHub Admins Prepare A Company For SOC 2 And ISO 27001 Audits
  • The Elusive Quest for DevSecOps Collaboration
  • Modern DevSecOps: Benefits, Challenges, and Integrations To Achieve DevSecOps Excellence
  • Deploy a Session Recording Solution Using Ansible and Audit Your Bastion Host

Partner Resources


Comments

ABOUT US

  • About DZone
  • Send feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: