Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix SecretGroup common policy path #392

Merged
merged 1 commit into from
Nov 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions PUSH_TO_FILE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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:<ul><li>A Conjur variable path</li><li> A key/value pairs of the form `<alias>:<Conjur variable path>` 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.<br><br>When this annotation is set, the policy paths defined by `conjur.org/conjur-secrets.{secret-group}` are relative to this common path.<br><br>When this annotation is not set, the policy paths defined by `conjur.org/conjur-secrets.{secret-group}` are themselves relative to the root policy.<br><br>(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.<br><br>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 `/`).<br><br>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:<ul><li>yaml (default)</li><li>json</li><li>dotenv</li><li>bash</li></ul>(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. |
Expand All @@ -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
Expand Down
24 changes: 10 additions & 14 deletions pkg/secrets/pushtofile/secret_group.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand All @@ -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,
Expand Down
16 changes: 9 additions & 7 deletions pkg/secrets/pushtofile/secret_group_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand All @@ -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",
Expand Down