Keys and operations

Store and limit keys

Keep keys out of source and normal logs, use managed key services where appropriate, and grant only required encrypt, decrypt, sign, or verify operations.

A key’s storage and permissions are part of the cryptographic design. The strongest algorithm cannot protect an exposed key, and most real-world crypto failures are key-handling failures, not broken math.

Start with the obvious exclusions. Keys never go in source control, and never in normal logs. A key committed once lives in git history forever, so treat any committed key as compromised and rotate it — deleting the file changes nothing:

git log -p --all -S 'BEGIN PRIVATE KEY' -- '*'
# any hit here means the key is burned, even if the file is gone

Where keys should live

Prefer a KMS, HSM, secure enclave, or protected secret store that can restrict operations and record use. The ladder looks like this: environment variables injected at deploy are better than files in the repo; a secret manager with access control and audit is better than environment variables; a KMS that performs operations without releasing the key is better still.

That last step changes the model. A managed key service can expose only a sign operation and keep raw key material inside the service. Your code sends bytes and receives a signature. Nothing that runs in your process can copy a key that never enters your process. This narrows authority, but access policy and audit logs become part of the cryptographic system — misconfigure the policy and the HSM protects an operation anyone can invoke.

Grant operations, not keys

Permissions should name operations, not just keys. An identity that verifies webhooks needs verify, never sign. A service that encrypts uploads needs encrypt, not decrypt:

identity            key            allowed
api-server          webhook-hmac   verify
upload-worker       storage-kek    encrypt
restore-job         storage-kek    decrypt
release-pipeline    signing-v3     sign

Here is why the narrow grant matters. A signing key is available as plaintext to the whole CI job, including formatting and test steps. A compromised test dependency can copy the same authority used for releases. Scope the key to the one signing step, or better, keep it in a service that only that step’s identity may call.

Separate keys by environment and purpose, and keep data and keys under different access paths when the architecture allows it. A backup containing both ciphertext and its keys protects nothing.

Practice

Build a key inventory with purpose, owner, environment, storage, allowed operations, users, rotation, and revocation. Save the effective policy and one audit event for an authorized test operation. Then attempt a forbidden operation, such as decrypting with a sign-only identity, and capture the denial.

Lesson completed

Take this course offline

Get every free book, course edition, and software download.

Get the download library →