{"id":28289633,"url":"https://github.com/karlbateman/praetorian","last_synced_at":"2025-06-13T05:31:31.481Z","repository":{"id":294040240,"uuid":"945523788","full_name":"karlbateman/praetorian","owner":"karlbateman","description":"A simple cryptographic key management service.","archived":false,"fork":false,"pushed_at":"2025-05-18T16:12:53.000Z","size":17,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"develop","last_synced_at":"2025-05-18T16:44:04.106Z","etag":null,"topics":["aes","aes-256","aes-encryption","compliance","cryptography","decryption","encryption","encryption-as-a-service","gdpr-compliant","golang","key-rotation","keyring"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/karlbateman.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-03-09T16:18:46.000Z","updated_at":"2025-05-18T16:12:56.000Z","dependencies_parsed_at":"2025-05-18T16:54:10.575Z","dependency_job_id":null,"html_url":"https://github.com/karlbateman/praetorian","commit_stats":null,"previous_names":["karlbateman/praetorian"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/karlbateman/praetorian","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlbateman%2Fpraetorian","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlbateman%2Fpraetorian/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlbateman%2Fpraetorian/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlbateman%2Fpraetorian/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/karlbateman","download_url":"https://codeload.github.com/karlbateman/praetorian/tar.gz/refs/heads/develop","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/karlbateman%2Fpraetorian/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259588912,"owners_count":22880868,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aes","aes-256","aes-encryption","compliance","cryptography","decryption","encryption","encryption-as-a-service","gdpr-compliant","golang","key-rotation","keyring"],"created_at":"2025-05-22T01:13:44.762Z","updated_at":"2025-06-13T05:31:31.466Z","avatar_url":"https://github.com/karlbateman.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Introduction\n\nPraetorian is a zero dependency, lightweight service which wraps and unwraps\ndata encryption keys over HTTP using a rotating root key. It is intentionally\nnarrow in scope and uses the 256-bit Advanced Encryption Standard (AES) in\nGalois Counter Mode (GCM). Its purpose is to provide a simplified method for\ndevelopers looking to implement [Envelope encryption], a technique used to\n[encrypting sensitive data at rest].\n\nEnvelope encryption is a technique where data is encrypted with a Data\nEncryption Key (DEK), the DEK is encrypted using a Key Encryption Key (KEK). The\nterm \"envelope\" refers to the process of wrapping one layer of encryption around\nanother, akin to sealing a letter with multiple layers of envelopes for added\nsecurity.\n\n- **Data Encryption Key (DEK)**: A unique key is generated for each set of data\n  to be encrypted. This key is used to encrypt and decrypt the data and should\n  be symetric.\n- **Key Encryption Key (KEK)**: A higher-level key used to encrypt and protect\n  the DEK. The KEK is an asymetric key stored securely in the Praetorian\n  environment configuration.\n\nPraetorian provides the Key Encryption Key which can be rotated and exposes HTTP\nendpoints so Data Encryption Keys can be wrapped and unwrapped, without leaking\nany Key Encryption Key material.\n\n[envelope encryption]: https://cloud.google.com/kms/docs/envelope-encryption\n[encrypting sensitive data at rest]: https://cloud.google.com/docs/security/encryption/default-encryption\n\n\u003e Throughout the remainder of this documentation, the term Key Encryption Key\n\u003e can be used interchangeably with Root Key.\n\n## Why use Praetorian?\n\nPraetorian is intended to be very easy to setup and great for startups looking\nto get moving quickly. If you're storing sensitive information in a database and\nwant a simplified approach to using envelope encryption, you should use\nPraetorian.\n\n## Deployment\n\nBefore you start, you'll need to create a valid Praetorian configuration. Run\nthe following command from your local terminal to generate a JSON configuration\nwhich contains a single root key which will be set as the active root key.\n\n```text\necho $(printf '{\"activeKeyId\": \"1\", \"rootKeys\": {\"1\": \"%s\"}}' \"$(openssl rand -base64 32)\")\n```\n\nHit the deployment button below and paste the JSON output from the previous\ncommand into the `PRAETORIAN_CONFIG` environment variable. Once the service has\nbeen built and deployed, Praetorian will be running and only available from the\nprivate interface.\n\n\u003e Do not expose your Praetorian service to the public internet!\n\n[![Deploy on Railway](https://railway.com/button.svg)](https://railway.com/template/pr7YF_?referralCode=O1su6l)\n\nWhen you deploy applications that interact with Praetorian, you will need to use `http://praetorian` as the base URL.\n\n## Usage\n\nBefore integrating Praetorian into your application, it's best to start with a locally running instance so you can explore and familiarise yourself with the envelope encryption flow.\n\nAssuming you have Docker installed, start by running the following command to get a Praetorian container running and listening for requests on port `3000`.\n\n```text\ndocker run --rm \\\n  --name=praetorian \\\n  --publish=3000:3000 \\\n  --env=PRAETORIAN_CONFIG=\"$(printf '{\"activeKeyId\": \"1\", \"rootKeys\": {\"1\": \"%s\"}}' \"$(openssl rand -base64 32)\")\" \\\n  karlbateman/praetorian\n```\n\nNow we have our Praetorian service running locally, we can issue a request to wrap a data encryption key using the following `curl` request.\n\n```text\ncurl --silent \\\n  --request POST \\\n  --data '{\"key\": \"abc123\"}' \\\n  http://localhost:3000/wrap\n```\n\nTo unwrap this data, simply copy the response from the terminal and send it to the `/unwrap` endpoint.\n\n```text\ncurl --silent \\\n  --request POST \\\n  --data '\u003creplace_with_wrap_response\u003e' \\\n  http://localhost:3000/unwrap\n```\n\nThis demonstrates the flow of wrapping and unwrapping data encryption keys.\n\n## Integrating\n\nWith Praetorian running in your Railway environment and accessible through a private networking address, the workflow is simple. Within your backend application, you would perform the following operations:\n\n1. Generate a cryptographically secure data encryption key.\n2. Use this key to encrypt the sensitive information.\n3. Send a `POST` request to `http://praetorian/wrap` with the data encryption key as a JSON request body.\n4. Store the response body and the encrypted sensitive information in your DB.\n\n\u003e Every write/update operation to your database should perform this flow to\n\u003e ensure maximum security and integrity of your data. Every data encryption key\n\u003e should be unique at the row/doc level.\n\nWhen you want to read the data, you must perform the following steps within your backend application.\n\n1. Read the encrypted data and the wrapped data encryption key.\n2. Send a `POST` request to `http://praetorian/unwrap` with the wrapped data encryption key as a JSON request body.\n3. Use the unwrapped data encryption key from the response to decrypt the sensitive information.\n\n\u003e Never store an unwrapped data encryption key.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarlbateman%2Fpraetorian","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkarlbateman%2Fpraetorian","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkarlbateman%2Fpraetorian/lists"}