Skip to content

Commit 9ffc89e

Browse files
committed
feat: Always include SecretString key for JSON secrets
This allows users to retrieve the raw JSON string value using useful when you need the entire JSON object as a string rather than accessing individual JSON keys. Changes: - Modified GetSecrets to always include SecretString in returned map - Updated existing tests to expect SecretString key in JSON results - Added test case for retrieving valid JSON as raw string - Updated documentation with example of retrieving JSON as string 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com> Signed-off-by: Vladimir Sitnikov <sitnikov.vladimir@gmail.com>
1 parent dc860c6 commit 9ffc89e

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

docs/backends.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,19 +314,22 @@ type: Opaque
314314

315315
###### Plain Text Secrets
316316

317-
AWS Secrets Manager can store plain text (non-JSON) secrets. To retrieve the entire plain text value, use `SecretString` as the key:
317+
AWS Secrets Manager can store plain text (non-JSON) secrets. To retrieve the entire secret value as a raw string (whether it's plain text or JSON), use `SecretString` as the key:
318318

319319
```yaml
320320
apiVersion: v1
321321
kind: Secret
322322
metadata:
323323
name: aws-example
324324
stringData:
325+
# Plain text secret
325326
sample-secret: <path:test-plaintext-secret#SecretString>
327+
# Or JSON secret as raw string
328+
json-as-string: <path:test-json-secret#SecretString>
326329
type: Opaque
327330
```
328331

329-
**Note**: If you need to access the secret value as a single string, use `#SecretString`. If the secret contains JSON, you can access its elements with `#keyName` (e.g., `<path:test-secret#username>`).
332+
**Note**: Use `#SecretString` to retrieve the raw secret value as a single string. If the secret contains JSON and you want to access individual elements, use `#keyName` (e.g., `<path:test-secret#username>`).
330333

331334
###### Versioned secrets
332335

pkg/backends/awssecretsmanager.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,8 @@ func (a *AWSSecretsManager) GetSecrets(path string, version string, annotations
8383
dat["SecretString"] = *result.SecretString
8484
return dat, nil
8585
}
86+
// Always include SecretString to allow retrieving raw JSON value
87+
dat["SecretString"] = *result.SecretString
8688
} else if result.SecretBinary != nil {
8789
utils.VerboseToStdErr("Get binary value for %v", path)
8890
dat = make(map[string]interface{})

pkg/backends/awssecretsmanager_test.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ func (m *mockSecretsManagerClient) GetSecretValue(ctx context.Context, input *se
3636
case "test-invalid-json":
3737
string := "{incomplete json"
3838
data.SecretString = &string
39+
case "test-json-as-string":
40+
string := "{\"username\":\"admin\",\"password\":\"secret123\"}"
41+
data.SecretString = &string
3942
}
4043

4144
return data, nil
@@ -51,7 +54,8 @@ func TestAWSSecretManagerGetSecrets(t *testing.T) {
5154
}
5255

5356
expected := map[string]interface{}{
54-
"test-secret": "current-value",
57+
"test-secret": "current-value",
58+
"SecretString": "{\"test-secret\":\"current-value\"}",
5559
}
5660

5761
if !reflect.DeepEqual(expected, data) {
@@ -79,7 +83,8 @@ func TestAWSSecretManagerGetSecrets(t *testing.T) {
7983
}
8084

8185
expected := map[string]interface{}{
82-
"test-secret": "previous-value",
86+
"test-secret": "previous-value",
87+
"SecretString": "{\"test-secret\":\"previous-value\"}",
8388
}
8489

8590
if !reflect.DeepEqual(expected, data) {
@@ -159,6 +164,19 @@ func TestAWSSecretManagerGetSecrets(t *testing.T) {
159164
t.Errorf("expected: %v, got: %v.", expected, data)
160165
}
161166
})
167+
168+
t.Run("Get valid JSON secret as raw string using SecretString key", func(t *testing.T) {
169+
secret, err := sm.GetIndividualSecret("test-json-as-string", "SecretString", "", map[string]string{})
170+
if err != nil {
171+
t.Fatalf("expected 0 errors but got: %s", err)
172+
}
173+
174+
expected := "{\"username\":\"admin\",\"password\":\"secret123\"}"
175+
176+
if !reflect.DeepEqual(expected, secret) {
177+
t.Errorf("expected: %s, got: %s.", expected, secret)
178+
}
179+
})
162180
}
163181

164182
func TestAWSSecretManagerEmptyIfNoSecret(t *testing.T) {

0 commit comments

Comments
 (0)