Written by Sneh Pandya
CI/CD pipelines are at the core of daily operations for technology. CI/CD is the most crucial in your technology stack, where the infrastructure has access to many different resources from the development and production environment. Ideally, the resources your pipelines have access to are analytics keys, code signing credentials, secure secrets, proprietary code, databases, etc. It is extremely important to keep your CI/CD system highly secure.
But how do you ensure that your pipelines are secured and stay secure in the future? There are best practices commonly referred to as DevSecOps. The security team and their capabilities are incorporated into DevOps practices, making security the responsibility of everyone in the team. In this article, we will discuss how to ensure your application is secure by adding continuous security validation to your CI/CD pipeline.
Secure Your Environment
Securing your environment is one of the most important steps in the process. This includes defining strict user policies and access roles for the team of developers to avoid conflict of data and unnecessary actions, like mistakenly pushing confidential files or data. Also, defining rules in the code repository via strategies like .gitignore is highly recommended and widely adopted.
The next step is to keep all the access of services communicating via auth tokens in check. This can be services like GitHub, GitLab, etc., which authenticate via strategies like OAuth to provide access to the CI/CD server. Ensuring strict policy rules for code repository access is extremely important.
The next step is to also make sure the code, programming language, platforms/frameworks and software used are updated to their respective latest releases, ensuring better performance with the latest security patches and updates from their respective platforms or software vendors.
Ideally, every project should have multiple environments, like testing, dev, staging and production. Here, the important part is that all of the environments will have their own set of credentials, so each of the environments is secured and prevents even the attackers from messing with all the layers. Keeping environment-specific credentials also helps prevent misuse of the credentials and unauthorized access to the developer team.
Codemagic uses OAuth tokens to perform various operations and communication, from listing branches to fetching the latest commit information, etc. The source code checked out during the build is deleted from the virtual machine after the build and is never stored on Codemagic. The integrity of your source code is protected by Codemagic.
Peer Code Reviews
Developers can improve the quality of their code with informal code reviews or formal inspections. Having said that, it is not possible to analyze every line of code. Teams should come up with a security checklist, such as OWASP’s Cheat Sheet Series, to perform the reviews. It is critical to run manual code reviews and keep vulnerabilities in check, as often, better implementation can be discussed between the team members for robust implementation of security.
Static Analysis Security Tests
Static analysis checks the code for software vulnerabilities and coding errors. Alongside identifying violations in coding best practices, they also detect security vulnerabilities in code, oftentimes even in the libraries imported. IDE plugins and linters should be incorporated by all the developers to standardize security in their efforts.
Dynamic Analysis Security Tests
Loosely coupled modules make a larger system. These systems can be tested and deployed for security vulnerabilities using dynamic analysis. Unlike static analysis, this examines the code from the outside in its running state, much like what a hacker or an attacker would do. These tests and scanners may not have dependencies on a specific language since they interact with the overall system from the outside.
Unit tests check and verify if the classes and methods that have been written are behaving as expected. To achieve this, specific scripts with unit tests are used to analyze misuse/abuse cases and search for common vulnerabilities. Developers should address all the edge cases and make the code reliable and fail-safe.
Functional Security Tests
Traditional testing focuses on what a program should do. Functional testing is usually written in a similar format. However, far greater importance is given in security testing to describing what parameters should not be allowed. The agile concept of user stories, which describe what users can do, has its concept twisted in the form of evil user stories, which are useful for functional security tests. For example, the pipeline should fail if the authentication token of the process trying to access resources is expired. The majority of the tools that work for unit testing can also work for functional testing.
Codemagic CI/CD security measures
Codemagic ensures reliable, robust and secure architecture for a seamless experience in terms of security. This includes multiple security layers in the infrastructure, like virtual private networks guarded by firewalls, separate virtual instances of machines, full-fledged SSL and HTTPS-only requests, encryption of stored data (like login and deployment credentials), etc.
The underlying infrastructure for Codemagic builds is secured with SSH or HTTPS protocols for all networking. This means that all the data you send to or receive from Codemagic is fully encrypted. Your builds are run on virtual machines on Mac minis or Mac Pros, which are also physically secured in data centers.
Security of source code
Codemagic uses source control systems, such as GitHub, GitLab or Bitbucket, to perform CI/CD operations. Once access is granted to your source code, the tokens are encrypted and then stored in our database. These specific tokens are accessed automatically without manual intervention and can only be used to check out the source code on virtual machines.
Encryption of sensitive data
Codemagic can automatically deploy iOS and Android apps to App Store Connect and Google Play Store on your behalf if you allow it. However, in order to deploy apps, the login credentials, certificates with private keys, provisioning profiles and keystore files are required. All credentials, certificates and keys provided to Codemagic are encrypted with strong passwords and kept securely in a private Google Cloud bucket, which the backend has no read access to. The sensitive files are securely downloaded during the build phase only where the build is running.
Codemagic uses a widely trusted and global partner, Stripe, for payment processing. Stripe is used and trusted by numerous companies all around the world, including Amazon, Google, Salesforce, Microsoft, Uber, National Geographic, Slack, Spotify and many more. No payment-related data is stored or processed by Codemagic.
Strong legal agreement
Read more about the Codemagic CI/CD security measures here.
Even with continuous security validation for every change introduced, hackers continuously change their approaches, and new vulnerabilities are always being discovered. Monitoring tools allow developers to help detect, prevent and address issues while the code is in production.
Keeping your CI/CD pipelines secure is more important than ever before, as these practices require access to development and production environments, analytics keys, code signing credentials and more. With the approaches and strategies outlined above, your pipelines will be much more secure. Yet, considering that the CI/CD pipelines leverage TaaS (Testing as a Service), it is also important to realize and remember that some of the aspects of CI/CD security make it tough to automate such policies. These aspects are shaped by the behavior and culture within the team.
Codemagic ensures the implementation of all the best practices for CI/CD pipelines and helps you build your mobile apps securely, providing a seamless and robust experience. Codemagic is committed to consistently adapting to the ever-evolving needs in the domain of security and CI/CD.
Sneh is a Product Manager based in Baroda. He is a community organizer at Google Developers Group and co-host of NinjaTalks podcast. His passion for building meaningful products inspires him to write blogs, speak at conferences and mentor different talents. You can reach out to him over Twitter (@SnehPandya18) or via email (firstname.lastname@example.org).