You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: resources/2025-11-11-secrets-redactdata.md
+63-29Lines changed: 63 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# Redacting Sensitive Data for Radius Resource Types
2
2
3
-
***Author**: Lakshmi Javadekar (@lakshmimsft)
3
+
***Author**: `Lakshmi Javadekar (@lakshmimsft)`
4
4
5
5
## Overview
6
6
@@ -135,15 +135,15 @@ The design introduces encryption and redaction mechanisms that minimize sensitiv
135
135
1.**Frontend (sync)**: Encrypts sensitive data (fields marked with `x-radius-sensitive` annotation), stores encrypted resource in database, queues async operation
136
136
2.**Backend (async)**: Reads resource from database (with encrypted data), decrypts sensitive fields in memory, immediately nullifies sensitive fields in database
137
137
3.**Recipe execution**: Executes recipe using in-memory decrypted data (never re-persisted to database)
138
-
4.**Completion**: Updates resource with recipe outputs (outputResources). On success, returns normal success result. On failure, returns `Result{Requeue: false}` to prevent retries that would fail due to missing sensitive data.
138
+
4.**Completion**: Updates resource with recipe outputs (`outputResources`). On success, returns normal success result. On failure, returns `Result{Requeue: false}` to prevent retries that would fail due to missing sensitive data.
139
139
140
140
Key components:
141
141
-**Type Converter** (`bicep-tools/pkg/converter`): Maps fields with `x-radius-sensitive: true` annotation to `secureString`/`secureObject` Bicep types during YAML-to-Bicep type conversion.
142
-
-**Frontend Controller**: Encrypts sensitive fields marked with `x-radius-sensitive` before database save using application-layer encryption (ChaCha20-Poly1305)
142
+
-**Frontend Controller**: Encrypts sensitive fields marked with `x-radius-sensitive` before database save using application-layer encryption (`ChaCha20-Poly1305`)
143
143
-**Backend Recipe Controller** (`pkg/portableresources/backend/controller/createorupdateresource.go`): Decrypts encrypted data, immediately redacts from database, then orchestrates recipe execution with in-memory data
144
144
-**GET Controller**: Checks schema for `x-radius-sensitive` annotations and redacts fields when `provisioningState` is not in `Succeeded` state. For other states perform redaction to ensure no encrypted data exposure.
145
145
146
-
-**Encryption/Decryption Logic**: Application-layer encryption using Go `crypto/cipher` package with ChaCha20-Poly1305 AEAD cipher, root key stored in Kubernetes secret
146
+
-**Encryption/Decryption Logic**: Application-layer encryption using Go `crypto/cipher` package with `ChaCha20-Poly1305 AEAD` cipher, root key stored in Kubernetes secret
147
147
-**No-Retry Logic**: Backend controller returns `Result{Requeue: false}` on all failure paths for resources with sensitive fields, requiring user resubmission on failure. Successful operations return normal success result.
148
148
149
149
### Architecture Diagram
@@ -234,7 +234,7 @@ sequenceDiagram
234
234
235
235
##### Application-Layer Encryption Details
236
236
- Store root key in a Kubernetes secret (similar to ucp-cert)
237
-
- Use Go's `crypto/cipher` package with ChaCha20-Poly1305 AEAD cipher
237
+
- Use Go's `crypto/cipher` package with `ChaCha20-Poly1305 AEAD` cipher
238
238
- Generate unique nonce per encryption operation
239
239
- Key rotation:
240
240
-**Initial implementation (Manual)**:
@@ -249,7 +249,7 @@ sequenceDiagram
249
249
1. System generates new key (version N+1)
250
250
2. Adds to secret alongside existing keys
251
251
3. Controllers hot-reload keys without restart
252
-
4. New encryptions use latest key version
252
+
4. New encryption uses latest key version
253
253
5. Decryption uses versioned key (old data still readable during transition)
254
254
6. After grace period (e.g., 24 hours), remove old key versions
255
255
- Benefits: Zero-downtime rotation, gradual migration, no data loss
@@ -259,7 +259,7 @@ sequenceDiagram
259
259
1. Check schema for fields with `x-radius-sensitive: true` annotation
260
260
2. For each sensitive field:
261
261
- Generate random 24-byte nonce
262
-
- Encrypt field value using ChaCha20-Poly1305 with root key and nonce
262
+
- Encrypt field value using `ChaCha20-Poly1305` with root key and nonce
263
263
- Store as: `{"encrypted": base64(ciphertext), "nonce": base64(nonce)}`
264
264
3. Save encrypted resource to database
265
265
@@ -268,7 +268,7 @@ sequenceDiagram
268
268
2. Check schema for fields with `x-radius-sensitive: true` annotation
269
269
3. For each encrypted field:
270
270
- Extract nonce and ciphertext
271
-
- Decrypt using ChaCha20-Poly1305 with root key and nonce
271
+
- Decrypt using `ChaCha20-Poly1305` with root key and nonce
272
272
- Store decrypted value in memory only
273
273
4. Nullify encrypted fields in resource: set to `null`
274
274
5. Save sanitized resource to database
@@ -280,7 +280,7 @@ sequenceDiagram
280
280
- Schema annotation missing: Skip encryption/decryption (treat as non-sensitive)
281
281
282
282
**Notes**:
283
-
- OpenSSL is CLI-only; Go crypto APIs are used for programmatic encryption
283
+
-`OpenSSL` is CLI-only; Go crypto APIs are used for programmatic encryption
284
284
-**Alternative considered**: Using initContainer to load root key as a file was discussed but rejected due to:
285
285
- Security concerns: Pod that can mount the volume could read the key
286
286
- Managing writes on pod restarts and scaling complexity with multiple pods
@@ -299,7 +299,7 @@ sequenceDiagram
299
299
- Kubernetes supports native etcd encryption via `EncryptionConfiguration`
300
300
- Transparent to Radius application code
301
301
- Document recommended encryption requirements.
302
-
-**Setup**: Kubernetes admin configures encryption provider (AES-CBC, AES-GCM, or KMS)
302
+
-**Setup**: Kubernetes admin configures encryption provider (`AES-CBC, AES-GCM, or KMS`)
- Existing functionality includes the Frontend PUT handler checking for existing resource and it will overwrite encrypted data with new request (normal PUT behavior) when user re-runs the deployment.
336
336
337
-
**Future Enhancement**: Background cleanup job to identify `Failed` resources older than configurable threshold (e.g., 24 hours) and nullify any encrypted fields within those resource entries.
337
+
**Cleanup**: Background cleanup job to identify `Failed` resources older than configurable threshold and nullify any encrypted fields within those resource entries.
338
338
339
339
#### Proposed Option
340
340
@@ -470,7 +470,7 @@ No changes required to Core RP. The implementation is isolated to dynamic-rp.
470
470
471
471
The design employs a **defense-in-depth approach** with multiple security layers:
472
472
473
-
1.**Application-Layer Encryption (Primary)**: Sensitive fields marked with `x-radius-sensitive` are encrypted using ChaCha20-Poly1305 AEAD cipher before database storage
473
+
1.**Application-Layer Encryption (Primary)**: Sensitive fields marked with `x-radius-sensitive` are encrypted using `ChaCha20-Poly1305 AEAD` cipher before database storage
474
474
2.**Short Exposure Window**: Encrypted data exists in database for few seconds (frontend save → backend redaction)
475
475
3.**In-Memory Processing**: Decrypted data exists only in process memory during recipe execution, never re-persisted
476
476
4.**GET Redaction**: Sensitive fields redacted in API responses during deployment to prevent exposure
@@ -524,6 +524,13 @@ Organizations deploying Radius with resources containing `x-radius-sensitive` fi
524
524
- Create Kubernetes Secret `radius-encryption-key` with 256-bit key
525
525
- Restrict access via RBAC to Radius service accounts only
526
526
- Rotate key periodically (manual process initially)
- User documentation for `x-radius-sensitive` annotation
688
722
- Installation guide for encryption key setup
689
723
- Troubleshooting guide
@@ -745,7 +779,7 @@ Pass sensitive data directly from frontend to async queue.without saving to data
745
779
746
780
## Design Review Notes
747
781
748
-
An earlier version of this design document focussed on detecting Radius.Security/secrets type and performing encryption/redaction for it's specific field. After discussions we updated the approach to now detect `x-radius-sensitive` annotation in any type and perform encryption/redaction for the sensitive fields.
782
+
An earlier version of this design document focused on detecting Radius.Security/secrets type and performing encryption/redaction for it's specific field. After discussions we updated the approach to now detect `x-radius-sensitive` annotation in any type and perform encryption/redaction for the sensitive fields.
0 commit comments