diff --git a/PUSH_TO_FILE.md b/PUSH_TO_FILE.md
index 1a42cd69..f33cd38f 100644
--- a/PUSH_TO_FILE.md
+++ b/PUSH_TO_FILE.md
@@ -8,6 +8,7 @@
- [Certification Level](#certification-level)
- [Set up Secrets Provider for Push to File](#set-up-secrets-provider-for-push-to-file)
- [Reference Table of Configuration Annotations](#reference-table-of-configuration-annotations)
+- [Example Common Policy Path](#example-common-policy-path)
- [Example Secret File Formats](#example-secret-file-formats)
- [Custom Templates for Secret Files](#custom-templates-for-secret-files)
- [Secret File Attributes](#secret-file-attributes)
@@ -238,9 +239,10 @@ Push to File operation.
conjur.org/authn-identity: host/conjur/authn-k8s/dev-cluster/test-app
conjur.org/container-mode: init
conjur.org/secret-destination: file
+ conjur.org/conjur-secrets-policy-path.first: secrets/
conjur.org/conjur-secrets.test-app: |
- - admin-username: secrets/username
- - admin-password: secrets/password
+ - admin-username: username
+ - admin-password: password
conjur.org/secret-file-path.test-app: "./credentials.yaml"
conjur.org/secret-file-format.test-app: "yaml"
spec:
@@ -303,6 +305,7 @@ for a description of each environment variable setting:
| `conjur.org/retry-interval-sec` | `RETRY_INTERVAL_SEC` | Defaults to 1 (sec) |
| `conjur.org/debug-logging` | `DEBUG` | Defaults to `false` |
| `conjur.org/conjur-secrets.{secret-group}` | Note\* | List of secrets to be retrieved from Conjur. Each entry can be either:
- A Conjur variable path
- A key/value pairs of the form `:` where the `alias` represents the name of the secret to be written to the secrets file |
+| `conjur.org/conjur-secrets-policy-path.{secret-group}` | Note\* | Defines a common Conjur policy path, assumed to be relative to the root policy.
When this annotation is set, the policy paths defined by `conjur.org/conjur-secrets.{secret-group}` are relative to this common path.
When this annotation is not set, the policy paths defined by `conjur.org/conjur-secrets.{secret-group}` are themselves relative to the root policy.
(See [Example Common Policy Path](#example-common-policy-path) for an explicit example of this relationship.)|
| `conjur.org/secret-file-path.{secret-group}` | Note\* | Relative path for secret file or directory to be written. This path is assumed to be relative to the respective mount path for the shared secrets volume for each container.
If the `conjur.org/secret-file-template.{secret-group}` is set, then this secret file path must also be set, and it must include a file name (i.e. must not end in `/`).
If the `conjur.org/secret-file-template.{secret-group}` is not set, then this secret file path defaults to `{secret-group}.{secret-group-file-format}`. For example, if the secret group name is `my-app`, and the secret file format is set for YAML, the the secret file path defaults to `my-app.yaml`.
| `conjur.org/secret-file-format.{secret-group}` | Note\* | Allowed values:- yaml (default)
- json
- dotenv
- bash
(See [Example Secret File Formats](#example-secret-file-formats) for example output files.) |
| `conjur.org/secret-file-template.{secret-group}`| Note\* | Defines a custom template in Golang text template format with which to render secret file content. See dedicated [Custom Templates for Secret Files](#custom-templates-for-secret-files) section for details. |
@@ -311,6 +314,27 @@ __Note*:__ These Push to File annotations do not have an equivalent
environment variable setting. The Push to File feature must be configured
using annotations.
+## Example Common Policy Path
+
+Given the relationship between `conjur.org/conjur-secrets.{secret-group}` and
+`conjur.org/conjur-secrets-policy-path.{secret-group}`, the following sets of
+annotations will eventually retrieve the same secrets from Conjur:
+
+```
+conjur.org/conjur-secrets.db: |
+ - url: policy/path/api-url
+ - policy/path/username
+ - policy/path/password
+```
+
+```
+conjur.org/conjur-secrets-policy-path.db: policy/path/
+conjur.org/conjur-secrets.db: |
+ - url: api-url
+ - username
+ - password
+```
+
## Example Secret File Formats
### Example YAML Secret File
diff --git a/pkg/secrets/pushtofile/secret_group.go b/pkg/secrets/pushtofile/secret_group.go
index 3bed85d7..93e3a95a 100644
--- a/pkg/secrets/pushtofile/secret_group.go
+++ b/pkg/secrets/pushtofile/secret_group.go
@@ -32,22 +32,16 @@ type SecretGroup struct {
// ResolvedSecretSpecs resolves all of the secret paths for a secret
// group by prepending each path with that group's policy path prefix.
-func (sg *SecretGroup) ResolvedSecretSpecs() []SecretSpec {
- if len(sg.PolicyPathPrefix) == 0 {
- return sg.SecretSpecs
- }
-
- specs := make([]SecretSpec, len(sg.SecretSpecs))
- copy(specs, sg.SecretSpecs)
-
- // Update specs with policy path prefix
- for i := range specs {
- specs[i].Path = strings.TrimSuffix(sg.PolicyPathPrefix, "/") +
- "/" +
- strings.TrimPrefix(specs[i].Path, "/")
+// Updates the Path of each SecretSpec in the field SecretSpecs.
+func resolvedSecretSpecs(policyPathPrefix string, secretSpecs []SecretSpec) []SecretSpec {
+ if len(policyPathPrefix) != 0 {
+ for i := range secretSpecs {
+ secretSpecs[i].Path = strings.TrimSuffix(policyPathPrefix, "/") +
+ "/" + strings.TrimPrefix(secretSpecs[i].Path, "/")
+ }
}
- return specs
+ return secretSpecs
}
// PushToFile uses the configuration on a secret group to inject secrets into a template
@@ -309,6 +303,7 @@ func newSecretGroup(groupName string, secretsBasePath string, annotations map[st
filePath := annotations[secretGroupFilePathPrefix+groupName]
fileFormat := annotations[secretGroupFileFormatPrefix+groupName]
policyPathPrefix := annotations[secretGroupPolicyPathPrefix+groupName]
+ policyPathPrefix = strings.TrimPrefix(policyPathPrefix, "/")
// Default to "yaml" file format
if len(fileTemplate)+len(fileFormat) == 0 {
@@ -320,6 +315,7 @@ func newSecretGroup(groupName string, secretsBasePath string, annotations map[st
err = fmt.Errorf(`unable to create secret specs from annotation "%s": %s`, secretGroupPrefix+groupName, err)
return nil, []error{err}
}
+ secretSpecs = resolvedSecretSpecs(policyPathPrefix, secretSpecs)
sg := &SecretGroup{
Name: groupName,
diff --git a/pkg/secrets/pushtofile/secret_group_test.go b/pkg/secrets/pushtofile/secret_group_test.go
index e8831213..ce64a228 100644
--- a/pkg/secrets/pushtofile/secret_group_test.go
+++ b/pkg/secrets/pushtofile/secret_group_test.go
@@ -100,8 +100,9 @@ func goodSecretSpecs() []SecretSpec {
func TestNewSecretGroups(t *testing.T) {
t.Run("valid annotations", func(t *testing.T) {
secretGroups, errs := NewSecretGroups("/basepath", map[string]string{
- "conjur.org/conjur-secrets.first": `- path/to/secret/first1
-- aliasfirst2: path/to/secret/first2`,
+ "conjur.org/conjur-secrets-policy-path.first": "/path/to/secret/",
+ "conjur.org/conjur-secrets.first": `- first1
+- aliasfirst2: first2`,
"conjur.org/secret-file-path.first": "firstfilepath",
"conjur.org/secret-file-template.first": `firstfiletemplate`,
"conjur.org/conjur-secrets.second": "- path/to/secret/second",
@@ -114,11 +115,12 @@ func TestNewSecretGroups(t *testing.T) {
}
assert.Len(t, secretGroups, 2)
assert.Equal(t, *secretGroups[0], SecretGroup{
- Name: "first",
- FilePath: "/basepath/firstfilepath",
- FileTemplate: "firstfiletemplate",
- FileFormat: "",
- FilePermissions: defaultFilePermissions,
+ Name: "first",
+ FilePath: "/basepath/firstfilepath",
+ FileTemplate: "firstfiletemplate",
+ FileFormat: "",
+ FilePermissions: defaultFilePermissions,
+ PolicyPathPrefix: "path/to/secret/",
SecretSpecs: []SecretSpec{
{
Alias: "first1",