Skip to main content

Utility to ensure SOPS secrets are encrypterd.

Project description

IsOPS: Is OPerations Secure

release codecov GitHub Workflow Status (with branch) pver MIT

__/\\\\\\\\\\\____________________/\\\\\_______/\\\\\\\\\\\\\_______/\\\\\\\\\\\___        
 _\/////\\\///___________________/\\\///\\\____\/\\\/////////\\\___/\\\/////////\\\_       
  _____\/\\\____________________/\\\/__\///\\\__\/\\\_______\/\\\__\//\\\______\///__      
   _____\/\\\______/\\\\\\\\\\__/\\\______\//\\\_\/\\\\\\\\\\\\\/____\////\\\_________     
    _____\/\\\_____\/\\\//////__\/\\\_______\/\\\_\/\\\/////////_________\////\\\______    
     _____\/\\\_____\/\\\\\\\\\\_\//\\\______/\\\__\/\\\_____________________\////\\\___   
      _____\/\\\_____\////////\\\__\///\\\__/\\\____\/\\\______________/\\\______\//\\\__  
       __/\\\\\\\\\\\__/\\\\\\\\\\____\///\\\\\/_____\/\\\_____________\///\\\\\\\\\\\/___ 
        _\///////////__\//////////_______\/////_______\///________________\///////////_____

IsOPS (Is OPerations Secure) is a minimal command line utility that helps you ensure that your secrets are encrypted correctly with sops before committing them. isops will read your configuration files, will scan all your secrets and alerts you if it finds any key that should be encrypted but it's not.

Installation

You can install isops via pip:

user@laptop:~$ pip install isops

The CLI is minimal:

user@laptop:~$ isops
Usage: isops [OPTIONS] PATH

  Utility to ensure all SOPS secrets are encrypterd.

Options:
  -s, --summary            Print a summary at the end of the checks.
  -h, --help               Show this message and exit.
  -v, --version            Show the version and exit.
  -r, --config-regex TEXT  The regex that matches all the config files to use.
                           [required]

You must provide a directory to scan and a regex that matches all the sops configuration files.

How it works?

isops is called with a directory and a regex. Then:

  1. It finds the config files using the provided regex.
  2. For each rule in creation_rules it finds the files according to the path_regex.
  3. For each file found, it scans all the keys, no matter how nested the yaml is, in search for those keys that match the encrypted_regex.
  4. For each matched key, it checks if the associated value matches the sops regex "^ENC\[AES256_GCM,data:(.+),iv:(.+),tag:(.+),type:(.+)\]".

If the config file doesn't provide a path_regex or a encrypted_regex, the default values are, respectively, ".ya?ml$" and "".

Usage example

Suppose you have this situation:

example
├── .sops.yaml
└── secret.yaml

A .sops.yaml:

creation_rules:
  - path_regex: (.*)?secret.yaml$
    encrypted_regex: "^(data|stringData)$"
    pgp: "FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4"

and a secret.yaml:

apiVersion: v1
data:
  key: aGhkZDg4OGRoODRmaDQ4ZmJlbnNta21rbHdtc2k4
kind: Secret
metadata:
  name: api-key
type: Opaque

If you run isops you get a warning because your secret is not encrypted:

user@laptop:~$ isops ./example --config-regex .sops.yaml
Found config file: example/.sops.yaml
---
example/secret.yaml::key [UNSAFE]
user@laptop:~$ echo $?
1

If the same secret is encrypted with sops:

apiVersion: v1
data:
    key: ENC[AES256_GCM,data:iCBh27Ort/dNVhP9D4y/AqI5d78U+2EHtHPX9u0/s9ANhA2VeqKSOQ==,iv:HkQVUgB6nvN3TU355K/PTU2NroahHAdoJhzJdgZFMwo=,tag:ayNppVmYJ/MLGrW9RtjV1A==,type:str]
kind: Secret
metadata:
    name: api-key
type: Opaque
sops:
    etc...

then isops will give you the green light:

user@laptop:~$ isops ./example --config-regex .sops.yaml
Found config file: example/.sops.yaml
---
example/secret.yaml::key [SAFE]
user@laptop:~$ echo $?
0

Another example

You can have a more complicated scenario where there are multiple sops configuration files, multiple environments and lots of secrets.

Suppose you have this situation:

example
├── .sops
│   ├── sops-dev.yaml
│   └── sops-prod.yaml
├── dev
│   ├── api-key-secret.yaml        <- Encrypted
│   ├── db-password-secret.yaml    <- Encrypted
│   ├── deployment.yaml
│   └── service.yaml
└── prod
    ├── api-key-secret.yaml        <- Not encrypted!
    ├── db-password-secret.yaml    <- Encrypted
    ├── deployment.yaml
    └── service.yaml

Then if you run isops you get:

user@laptop:~$ isops example --config-regex "example/.sops/(.*).yaml$"
Found config file: example/.sops/sops-dev.yaml
Found config file: example/.sops/sops-prod.yaml
---
example/dev/db-password-secret.yaml::password [SAFE]
example/dev/api-key-secret.yaml::key [SAFE]
example/prod/db-password-secret.yaml::password [SAFE]
example/prod/api-key-secret.yaml::key [UNSAFE]

Sometimes the list of secret is very long: you can enable a small summary at the end with the --summary option:

user@laptop:~$ isops example --config-regex "example/.sops/(.*).yaml$" --summary
Found config file: example/.sops/sops-dev.yaml
Found config file: example/.sops/sops-prod.yaml
---
example/dev/db-password-secret.yaml::password [SAFE]
example/dev/api-key-secret.yaml::key [SAFE]
example/prod/db-password-secret.yaml::password [SAFE]
example/prod/api-key-secret.yaml::key [UNSAFE]
---
Summary:
UNSAFE secret 'key' in 'example/prod/api-key-secret.yaml'
3 safe 1 unsafe

The previous example can be found in the example directory. The sample application was generated by ChatGPT with the prompt: "Please, generate an example Kubernetes application with two secrets".

pre-commit hook

isops can be also used as a pre-commit hook. For example:

repos:
  - repo: https://github.com/lorenzophys/isops
    rev: v0.2.0
    hooks:
      - id: isops
        args:
          - --config-regex=.sops/(.*).ya?ml$
          - --summary

License

This project is licensed under the MIT License - see the LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

isops-0.3.0.tar.gz (7.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

isops-0.3.0-py3-none-any.whl (9.7 kB view details)

Uploaded Python 3

File details

Details for the file isops-0.3.0.tar.gz.

File metadata

  • Download URL: isops-0.3.0.tar.gz
  • Upload date:
  • Size: 7.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/24.6.0

File hashes

Hashes for isops-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b512d5c2a5f95064f517dc795acc6cce054088d6ebdd8c45aef9cc6459ee1a2f
MD5 4ca9dcb250cf4f78048b3614d9fa6c9d
BLAKE2b-256 3a2ea0db1af0bffcac6299fad0bb850c9f9d4259887192c30f839d9149f0b0bc

See more details on using hashes here.

File details

Details for the file isops-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: isops-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 9.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/2.2.1 CPython/3.14.0 Darwin/24.6.0

File hashes

Hashes for isops-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 23a09dcfe753a18bcf13287040c3d390471bb9ddeea564fd159fc0c320ee706c
MD5 f26638f7dde0f7e7dbdb327e34e1bae6
BLAKE2b-256 9e7747d850c0233efe18eb82a191ac4d87e3da41b53fca3e1e732852b58d503d

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page