SOPS
SOPS (Secrets OPerationS) is a structured format for managing secret keys. It belongs to the SOPS application (Simple and flexible tool for managing secrets) and allows users to create encrypted key-value pairs for managing secrets. The utility is potentially helpful for development teams managing keys across projects. The primary formats that SOPS supports are JSON
and YAML
.
Contents[hide] |
About
SOPS is initialized within your default editor using a key, e.g. PGP key. You can then proceed to create a data structure as you chose, the idea being, the keys in your structure will be encoded in plain-text once saved, and your values, again, once saved, will be encrypted. Similarly, decryption requires your keys to decode the SOPS structure back into the original data structure you began with.
Configuration and examples
Test install
An example from the SOPS README shows how to test the utility using its example pgp key:
git clone https://github.com/getsops/sops.git cd sops cd cmd go mod tidy go build gpg --import pgp/sops_functional_tests_key.asc
Example YAML
Given the above, you can then elect to edit a YAML file:
./sops edit example.yaml
SOPS will bring up a default object, although this can be deleted and you can encode any structure.
hello: Welcome to SOPS! Edit this file as you please!! example_key: example_value # Example comment example_array: - example_value1 - example_value2 example_number: 1234.56789 example_booleans: - true - false
When this file is saved, values are wrapped with semantic information to help decoding, and a 'sops'
key created containing decode and encryption specific information.
hello: ENC[AES256_GCM,data:uHToaQKhNuSRfJLfVPmBBAYzwDcA7OQ/gyd8AZqPtdAszHk4SevC6xA34x55tXU=,iv:M/ni78KR8us2zBf4myH+8QsivUyudM8DSKGdx0j7ltc=,tag:zECH/1665g+ebSu5HL0ppw==,type:str] example_key: ENC[AES256_GCM,data:MjFv3ewfpq1Sq+3WJg==,iv:NT/Yb3XawHuX/ypbzm9WPRLIar11Fq5uF0vJJtLgphY=,tag:wzlXdbtQBqmUpNcO3GQkng==,type:str] #ENC[AES256_GCM,data:HlTEj04aNP48sytIFPQhaQ==,iv:CWuWsTk7TmfFAyYUkwW/8xAv2XxY/bwwfCrayo5cCmE=,tag:CEpvfAM6PTZQHxhPv4f0ag==,type:comment] example_array: - ENC[AES256_GCM,data:4KxwWTHxEf3LDPx7UFc=,iv:l6caTOPmKxQFK+uREVzgezu2LbCyTEHTMu5bIJdm8+A=,tag:pjsY69yWWvbbGyqtAsPaUQ==,type:str] - ENC[AES256_GCM,data:vaTUurETsaYDJ6B1A5g=,iv:2UxiUDn6jWFyaZO8micUf/n98ELHLQYWzG74gpCVpy4=,tag:4NB/X0spcKHhbnOmYtZPZQ==,type:str] example_number: ENC[AES256_GCM,data:816+HcmStO0rpQ==,iv:VLXvtL9uLeylWLzvmXG/kKnxgzE8QuSmWqPGH6su4Fg=,tag:xxCmwfupJWjiO7jf4toHcA==,type:float] example_booleans: - ENC[AES256_GCM,data:vtkQiA==,iv:cxbZA3eecGy4XfF6rO2kI4ime9d7gKTqSPSz39tm9Fo=,tag:V71+rHj44N1tiu7uJlHiHg==,type:bool] - ENC[AES256_GCM,data:Cmv7aVs=,iv:FuyQn7wJrsPXRcloqtOq+PxNvY5DrCRISwGlUsVnmRQ=,tag:cJzDzUJavUbbcBapzQNh1g==,type:bool] sops: kms: [] gcp_kms: [] azure_kv: [] hc_vault: [] age: [] lastmodified: "2025-02-26T15:24:03Z" mac: ENC[AES256_GCM,data:iOigwJNFsPFZ2+hERTWE38izLH7QjiM/I+dxZLpEO8u0dkep/xh1BgtLHJMVspUisq4zI0XOwq4+ZTwpIOpC6yzaLt20X/2cLtWy5ZGlm3Vgo3iT0N7cbggKtXoSZ1XdzY9YP1bQl7grS8bnXYYeIKo5uJO517/nxydtaRYgJc0=,iv:rkE8ti+ZPTZnVlr8Aro32SfT9Lo3XDjUCOvbRqk5OHw=,tag:u5A+2ce1Ojmd6vnYHKm28Q==,type:str] pgp: - created_at: "2025-02-26T15:24:00Z" enc: |- -----BEGIN PGP MESSAGE----- hQEMAyUpShfNkFB/AQf/c7gcIWuhhsSfP9rd/ZAicTmh7+SM0GJhMR28snWBD/Sc sxYqZm+utqJW14Woi/XQUKrC7sanNguUNkCk6SKPKAWnQ+CjzaUlISbDyQwgKpQn eqr2q/5sFxWpFtzQpryK7lQzhIMbKhIKZh1xliLsL4Knkm2I7FO+KDBfVvJ9lwcR 4dBhXQdZySH4YNDT6Z7zK9o4cXswKa7OgoVHPVtqEHaDc2sA6GKBmrio3A9x5BAX xbf1r6FfT/XPFP1AlmV1Ixiu80lurfp39SuDfoHU7uVthrK7Oo9A7nd/Uu9zdS5O 7aPrbcSRtTN6ntglm3X/sU6oxgehVaTxipnW79XNntJeAXkFWLo5WMVCaIwXyenM uCfxeGd+fxL2k1miZC+7cXDorv5FfpAAQGURh3KbujHQ0n+ZriqW0wzYgweMSbFT skINiavro2+ocZXNrVZWWkexy2P8evcMWPVbVQ5HGw== =KkKj -----END PGP MESSAGE----- fp: FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4 - created_at: "2025-02-26T15:24:00Z" enc: |- -----BEGIN PGP MESSAGE----- hIwDXFUltYFwV4MBA/92mfagks7hCLfAGCuT2yFinvIheHTTfQn/sRHMkU4YsDDs 79fFtpAQRhiEe+2dcHP9QY4vNzk6G8yHnvSrpjkLlBz15F//2DTgPQGK0hutNo4n PMx+a99RSlvy2GJ/nSS2dBHJBj3JOt6iDk+eVzYQjDo4zjf+qeFm2m4QMkXqNNJe AY9AJ23ifr0tyhrlGbVd4KNcJmJLg6Vz3nxvG8r7TSLt91bTMUOi6owLkTFl+Tij X63YSoEauQzc/tSRKJfNFi5No173krsqXFQLyt2LrSPakZ0xgDGwU+fn2KCnmw== =Bj+H -----END PGP MESSAGE----- fp: D7229043384BCC60326C6FB9D8720D957C3D3074 unencrypted_suffix: _unencrypted version: 3.9.4
Example JSON
Alternatively, you can elect to edit a JSON file:
./sops edit example.json
SOPS will bring up a default object, although this can be deleted and you can encode any structure.
{ "hello": "Welcome to SOPS! Edit this file as you please!!", "example_key": "example_value", "example_array": [ "example_value1", "example_value2" ], "example_number": 1234.56789, "example_booleans": [ true, false ] }
When this file is saved, values are wrapped with semantic information to help decoding, and a 'sops'
key created containing decode and encryption specific information.
{ "hello": "ENC[AES256_GCM,data:5t8seVgX/GxsD6muvKOnVgPjNk8yoX/Gbp3xCt0KuOH0yENKC0I6zyWUBgE0jIE=,iv:iPM4TVZ0GlQMZgEUWbGS+SHNVD0JF8uqT/X+VOij/dw=,tag:8Hnl4Giec2IcriApyc/CLA==,type:str]", "example_key": "ENC[AES256_GCM,data:LRMvnB36y2AvtrSbFw==,iv:kQ0LE2msZc50QHJhT+V84XbSiUA4yiynztJ/WvOVnFk=,tag:3hP8QJLPWezJ0lqiy7B+Vw==,type:str]", "example_array": [ "ENC[AES256_GCM,data:rENwn4lVjLQmb06OZo8=,iv:lI6HEkYkOmNavvMczUpc1QdE6sf4oZionB0EAk5o5TM=,tag:Niew51lQ87+JUMJQ0+Qpjw==,type:str]", "ENC[AES256_GCM,data:cxogL0GVCcgMA7D0bRY=,iv:zblA1Uo6FwYDkRj2RQ/Rv26lGY+Kcqy1IeDHyeJy/JQ=,tag:Pr9BIh1fG5cTKaZLJXuEGw==,type:str]" ], "example_number": "ENC[AES256_GCM,data:6l6Ez2VJm9AAsw==,iv:24bAR3EGZ+WHK0/4T+hB7/SLeVQ/8m3PsB5k6rYO0qY=,tag:ZVeEwIV0u4Mh48hf5kgjJg==,type:float]", "example_booleans": [ "ENC[AES256_GCM,data:sla9Gw==,iv:iMuyEFbO4GF5UkSiJY7eJeMd8TtCFtyHpzi0kbQMV60=,tag:nRUuew9bfSXLuZ4sKZr0Pg==,type:bool]", "ENC[AES256_GCM,data:LmA/l6U=,iv:M5QXLpIRMgH/RpJ6qlU+VtPytJUCT1RdE4FPsQ/WGyc=,tag:9nkIJHA9EQ+PMQVUUgyMSg==,type:bool]" ], "sops": { "kms": null, "gcp_kms": null, "azure_kv": null, "hc_vault": null, "age": null, "lastmodified": "2025-02-26T15:43:02Z", "mac": "ENC[AES256_GCM,data:0LWYLJbAbflAzS9URkFFAUzMtZCpqd8KnLQWYQLPJv5x8d9K9zNRh3meRX3PembwtZcr64IoVAJY3ft8Ttt6Dmww+UIhFQAvo8nmbDp3QVwUXzLgpFIodhNyUjSOm3Dj9ZVRXy5emHyd5Ai1ocQ7aUvN/Tj03Cb8DAw9Bf3Z+OU=,iv:S7edialcrk6AHV4UTedYXxVQpz342gpObFypzDdW3X4=,tag:CCpqLgKtnp1sqlgCVUrxnA==,type:str]", "pgp": [ { "created_at": "2025-02-26T15:42:52Z", "enc": "-----BEGIN PGP MESSAGE-----\n\nhQEMAyUpShfNkFB/AQf/XGtcWkKvKJX2Q5gky+ewG+BjIok6Ruw0Q5oebuawTgh0\nxHWN6miY/YSoq4jmz47u5QRYiPxfQ6kmeHYjbrkDJwkqev3dQ9e9X+Auk38W+EiT\nyDYxP9uML+d2GdG9irrHkeeMqZs7NPbohS2AQpT5NgA19PQB2PvwscMRZtOCjnEb\nTJcVZYkHQgXlLHJ6AdmNqneIwca6dN5x6pDnfys8oErK9bl5bsDAzm8LzOzIKHkf\nLKWRNyXkE2VBLjaTU431k7zXvG7F1BcA3BuaLhJaAPEkjg8wSy2H0Mx1fcTNoqfI\ncezuL+BUgNR0C2JVAzqgiP/92FADXl9NJpHCG+JzJdJcAdY8JIXqYcmJZqQYu82+\nNwykwnrdu6r/RWkDk0P+/u6GKVz6KCkAn5p9e45zs/z1fv1KfQMCM58w6fTEIdDW\n0sChyjEmxZq8wuu6c3xKxyCihVvL6SgIaY483zM=\n=794N\n-----END PGP MESSAGE-----", "fp": "FBC7B9E2A4F9289AC0C1D4843D16CEE4A27381B4" }, { "created_at": "2025-02-26T15:42:52Z", "enc": "-----BEGIN PGP MESSAGE-----\n\nhIwDXFUltYFwV4MBA/wJkpY5y4wGupEEJKOwomPtCFDTCgn7ug3KFFMAbHm3lz6M\nd+a2CPr3jSEpyjE1VbLAWnxFpfoDTNzqOdWmCbwRkNCjV3ih9Y0SLVL0al/STz1T\nLQw99VN3IRMbTO9wbQ/OpyS+rodP4W/EmzHR5DQCqNH+8A/koWsjc1Fz/zIqC9Jc\nAQh0P381qCx5lbow8JaBmYZ9BE2qDmRC2uw0W8LYNP7sWAVxSXfwTqNV3YEtomnf\nQGGPnRKnGq3HrTgCKE9pAypYcCSariQEDV2aM6v8C5cfocVY6tco16qG2bg=\n=VpnI\n-----END PGP MESSAGE-----", "fp": "D7229043384BCC60326C6FB9D8720D957C3D3074" } ], "unencrypted_suffix": "_unencrypted", "version": "3.9.4" } }
Identification
It should be possible to create a signature from the SOPS data structure, looking for the 'sops'
key and some of the values encoded within there, e.g 'lastmodified'
and 'mac'
are two important values for the format. Additional details here, and understanding of the format will benefit signature research.