I get asked quite a bit about how to build security into your DevSecOps work and CI CD pipelines. I had the great opportunity to share my knowledge in my role as a subject matter expert (SME) in this area and I mentored some University of Washington (UW) students with their related project. This is a write up I did for them. The info about their project is at the end of this article.
I’ve decided to share the basics, fundamentals of security in this article in order to help you be successful in your DSO and CI CD journey, no matter what platform you are using. In this case I will refer to Github and AWS as they are likely the most used and arguably the most accessible platforms, providing free accounts on Github and AWS provides a free tier as well:
These end up becoming “after-thoughts” but if you understand these things way up front, it will help you be more successful much quicker. Here is the list with some basic definitions:
Access keys, secrets or credentials, aka your passwords: Two main types in CI/CD – shortlived, long lived. Long lived need rotation in 90, 180 days. Short lived usually expire quickly. – Usually referring to a person’s keys or credentials to access a system. Never store these in the code within your pipelines, or open/plain text or within your application code. Don’t share them with others. Always keep them encrypted. If you need to use them temporarily for dev purposes, instead of putting them in your code, keep them in services such as “Github Secrets”.
Personal Access Tokens (PATs) – Similar to an individual’s keys or access credentials.
Account Names or Account Numbers (i.e. your personal account names or cloud account numbers) – Not as critical to keep encrypted but still, do not share them widely and it may be ok to keep the account name in code, just don’t overdo it.
Service Accounts – Accounts used in automation by a pipeline. Don’t put the passwords/credentials in your code in plain text. You can put the “account name” in code in some circumstances but its better to keep it in your key vaults or pipeline vaults wherever possible.
Service Roles – These may be more an AWS thing but other clouds do something similar. You may have a role for each cloud service like a “CloudFormation Role” or an “S3 Bucket Role” or an “Elastic Beanstalk Role” i.e. these roles are paired with your cloud services. These roles are used instead of passing your cloud account password credentials around in your code or instead of using your personal account passwords. Your pipeline and code can temporarily “assume a service role” like “assume the S3 Bucket role” etc. https://docs.aws.amazon.com/aws-backup/latest/devguide/iam-service-roles.html
IAM Policies & ACLs – These are Identity and Access Management (IAM) policies and Access Control Lists (ACL) that are used to control what a given service has access to, what it’s permissions are or for ACLs “an ACL allows only a finite set of permissions compared to the number of permissions that you can set in an access policy“. Each service role may have an attached policy or it may just be defined with a set of permissions. There are security policies applied to your account or to your cloud account or to your organization’s account etc. https://docs.aws.amazon.com/aws-backup/latest/devguide/security-iam-awsmanpol.html
https://docs.aws.amazon.com/AmazonS3/latest/userguide/acl-overview.html
Cloud “Tenant” Accounts – The various cloud providers may call them by different names i.e. “Azure Subscription Account” or “AWS Account” https://docs.aws.amazon.com/organizations/latest/userguide/orgs_getting-started_concepts.html or a “GCP Project Account”.
API keys – You may have used these if you ever needed to get access to an API on the web. These are basically just a key to be able to call an API
Certificates – While the cloud and DevSecOps to a degree are frequently changing, certificates and cryptography have been around a long time and likely will continue to be around a long time. You should learn the basics of how certificates work.
Public keys, private keys – Your public key can be available publicly, your private key should always be encrypted, stored safely in a cloud Certificate manager of some kind or similar key vault or certificate manager or cert vault. Never put your private key in your code.In summary, store sensitive information like API keys, tokens, and passwords as encrypted secrets within your repository’s settings or your cloud provider’s key vault (Azure) or AWS Secrets manager, etc. For Github, access these secrets within your GitHub Actions workflows using environment variables.
Here are some great examples of CI CD pipelines and DevSecOps that implement many of the above items I have listed and they do it right:
This is an even more “cloud native” deployment where you use less of Github actions and no VMs and more of the cloud native services on AWS for your CI/CD pipeline. Also instead of using “OpenIDConnect” and messing with all that and key management complexity, you just do a “webhook” and manage all your security within the cloud provider. Very clean, from this article: https://aws.amazon.com/blogs/devops/integrate-github-monorepo-with-aws-codepipeline-to-run-project-specific-ci-cd-pipelines/
This next one is a little more complex, but just ignore the whole “cross acount thing” just focus on the fact it is showing the “assume role” aspect. That is a great feature of this CI CD pipepline:
From this article. Also ignore the AWS CDK, that thing isn’t required. Using cloudformation alone or just uploading deployment assets with S3 without CDK is better in my experience. https://aws.amazon.com/blogs/devops/cross-account-and-cross-region-deployment-using-github-actions-and-aws-cdk/
Here is the UW student’s capstone project info:
https://ischool.uw.edu/capstone/projects/2024/open-devsecops
https://github.com/open-devsecops
https://open-devsecops.github.io