Automated SOPS compliance checking with sops-check
While SOPS files are considered secure by themselves, the security posture actually depends entirely on protecting these external trust anchors - and on controlling the trust anchors added to a SOPS file. SOPS files are often used with cloud-based key management systems (KMS), which has the great advantage of providing an online identity verification prior to granting access to the encrypted data. A malicious actor — especially an internal one — could simply add a "personal" trust anchor, e.g. a personal AGE key, to gain access to the encrypted data. He could thus copy a SOPS file and decrypt it without access to the online cloud-based KMS, and without leaving a trace in the audit trail.
See my talk "Cloud & Offline Secrets Management with SOPS" for more details about all of this:
SOPS-CHECK TO THE RESCUE
To turn SOPS files into a true secrets management solution we must therefore closely guard our SOPS files and exercise tight control over the trust anchors that are used in SOPS files. To help with this problem I'm proud to present sops-check, an Open Source tool to perform static compliance checking on SOPS files. You can find it at github.com/Bonial-International-GmbH/sops-check.
It allows defining rules that all SOPS files in a directory (e.g. a Git repo)
must comply with. The sops-check repository contains a demo to illustrate
this. In this demo we have the following rules:
- Our AGE disaster recovery key must be used to ensure our ability to decrypt an offline backup of our Git repositories that contain SOPS files
- Different AWS KMS keys must be used for the production, development and staging environments. This prevents accidential mix-ups between the different environments.
- All KMS keys must be from our allowed regions and accounts
No other trust anchors are allowed. The sops-check configuration file .sops-check.yaml looks like this:
# Global settings allowUnmatched: false # Reject any trust anchors not explicitly allowed by rules rules: # All rules must match - allOf: # Disaster recovery key must be present in all files - description: "Disaster recovery AGE key must be present in all files" match: "age1u79ltfzz5k79ex4mpl3r76p2532xex4mpl3z7vttctudr6gedn6ex4mpl3" url: "https://internal-wiki/security/disaster-recovery" # Environment-specific rules - anyOf: # Production rules - allOf: - description: "Production files must use production KMS keys in both regions" matchRegex: "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/production-cicd$" - not: description: "Production files must not use staging or development keys" anyOf: - matchRegex: "^arn:aws:kms:.*:alias/staging-cicd$" - matchRegex: "^arn:aws:kms:.*:alias/development-cicd$" description: "Production environment rules" url: "https://internal-wiki/security/production-keys" # Staging rules - allOf: - description: "Staging files must use staging KMS keys in both regions" matchRegex: "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/staging-cicd$" - not: description: "Staging files must not use production or development keys" anyOf: - matchRegex: "^arn:aws:kms:.*:alias/production-cicd$" - matchRegex: "^arn:aws:kms:.*:alias/development-cicd$" description: "Staging environment rules" url: "https://internal-wiki/security/staging-keys" # Development rules - allOf: - description: "Development files must use development KMS keys in both regions" matchRegex: "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/development-cicd$" - not: description: "Development files must not use production or staging keys" anyOf: - matchRegex: "^arn:aws:kms:.*:alias/production-cicd$" - matchRegex: "^arn:aws:kms:.*:alias/development-cicd$" description: "Development environment rules" url: "https://internal-wiki/security/development-keys" # Only allow KMS keys from allowed regions, account, and alias pattern - matchRegex: "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/(production|staging|development)-cicd$" description: "Only allow KMS keys from eu-central-1 or eu-west-1, account 123456789012, and alias ending with -cicd" url: "https://internal-wiki/security/authorized-regions"
Running sops-check produces an output like this, explaining in detail the errors found:
❯ make demo Running sops-check on demo directory... Found issues in demo/bad/malicious-pgp-key.yaml: [allOf] Expected ALL of the nested rules to match, but found 2 failures: 1) [anyOf] Expected ANY of the nested rule to match, but none did: 1) [allOf] Production environment rules More details: https://internal-wiki/security/production-keys Expected ALL of the nested rules to match, but found one failure: 1) [matchRegex] Production files must use production KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/production-cicd$" was not found. 2) [allOf] Staging environment rules More details: https://internal-wiki/security/staging-keys Expected ALL of the nested rules to match, but found one failure: 1) [matchRegex] Staging files must use staging KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/staging-cicd$" was not found. 3) [allOf] Development environment rules More details: https://internal-wiki/security/development-keys Expected ALL of the nested rules to match, but found one failure: 1) [matchRegex] Development files must use development KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/development-cicd$" was not found. 2) [matchRegex] Only allow KMS keys from eu-central-1 or eu-west-1, account 123456789012, and alias ending with -cicd More details: https://internal-wiki/security/authorized-regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/(production|staging|development)-cicd$" was not found. Unmatched trust anchors: - 1234567890ABCDEF1234567890ABCDEF12345678 Found issues in demo/bad/missing-age-key.yaml: [allOf] Expected ALL of the nested rules to match, but found one failure: 1) [match] Disaster recovery AGE key must be present in all files More details: https://internal-wiki/security/disaster-recovery Expected trust anchor "age1u79ltfzz5k79ex4mpl3r76p2532xex4mpl3z7vttctudr6gedn6ex4mpl3" was not found. Found issues in demo/bad/mixed-environments.yaml: [allOf] Expected ALL of the nested rules to match, but found one failure: 1) [anyOf] Expected ANY of the nested rule to match, but none did: 1) [allOf] Production environment rules More details: https://internal-wiki/security/production-keys Expected ALL of the nested rules to match, but found one failure: 1) [not] Expected nested rule to fail, but it did not: 1) [anyOf] Production files must not use staging or development keys Matched trust anchors: - arn:aws:kms:eu-west-1:123456789012:alias/staging-cicd 2) [allOf] Staging environment rules More details: https://internal-wiki/security/staging-keys Expected ALL of the nested rules to match, but found one failure: 1) [not] Expected nested rule to fail, but it did not: 1) [anyOf] Staging files must not use production or development keys Matched trust anchors: - arn:aws:kms:eu-central-1:123456789012:alias/production-cicd 3) [allOf] Development environment rules More details: https://internal-wiki/security/development-keys Expected ALL of the nested rules to match, but found 2 failures: 1) [matchRegex] Development files must use development KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/development-cicd$" was not found. 2) [not] Expected nested rule to fail, but it did not: 1) [anyOf] Development files must not use production or staging keys Matched trust anchors: - arn:aws:kms:eu-central-1:123456789012:alias/production-cicd Found issues in demo/bad/unauthorized-region.yaml: [allOf] Expected ALL of the nested rules to match, but found 2 failures: 1) [anyOf] Expected ANY of the nested rule to match, but none did: 1) [allOf] Production environment rules More details: https://internal-wiki/security/production-keys Expected ALL of the nested rules to match, but found one failure: 1) [matchRegex] Production files must use production KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/production-cicd$" was not found. 2) [allOf] Staging environment rules More details: https://internal-wiki/security/staging-keys Expected ALL of the nested rules to match, but found one failure: 1) [matchRegex] Staging files must use staging KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/staging-cicd$" was not found. 3) [allOf] Development environment rules More details: https://internal-wiki/security/development-keys Expected ALL of the nested rules to match, but found one failure: 1) [matchRegex] Development files must use development KMS keys in both regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/development-cicd$" was not found. 2) [matchRegex] Only allow KMS keys from eu-central-1 or eu-west-1, account 123456789012, and alias ending with -cicd More details: https://internal-wiki/security/authorized-regions Trust anchor matching regular expression "^arn:aws:kms:eu-(central|west)-1:123456789012:alias/(production|staging|development)-cicd$" was not found. Unmatched trust anchors: - arn:aws:kms:us-east-1:123456789012:alias/unauthorized-key ❌ Found 4 files with issues: - demo/bad/malicious-pgp-key.yaml - demo/bad/missing-age-key.yaml - demo/bad/mixed-environments.yaml - demo/bad/unauthorized-region.yaml make: *** [demo] Error 1
I hope that this little automated compliance checking tool will help you to establish a better security posture of your SOPS files. Big thanks go to Martin Ohmann for writing the tool!
Note: If the above Git repo doesn't yet contain the demo code then please check out my fork github.com/schlomo/sops-check instead. The PR is currently pending.
What are your automated compliance challenges? Tektit Consulting and I are happy to assist you with resolving them and helping you to fully automate all your compliance requirements.
Comments
Post a Comment