1Password/onepassword-operator

Please replace "itemPath" with two parameters: "vault" and "item"

rkr-kununu opened this issue · 3 comments

Summary

The OnePasswordItem CRD "itemPath" and annotations "operator.1password.io/item-path" makes it difficult to create a consistent staging and production deployment, where the only variant is the vault that's used.

Consider separating this into two fields: "vault" and "item".

Use cases

If I have a production and a staging environment, I want to have them be nearly identical. However, I want them to use different credentials... in terms of 1Password, separating them into two different vaults ("staging", "prod") seem to be the most logical choice.

However, this means your OnePasswordItem need to have an itemPath in the syntax of vaults/<vault_id_or_title>/items/<item_id_or_title>. Unfortunately, partial strings replacements with tools like Kustomize is not possible. It prefers the full text replacement of certain fields (for example using the ReplacementTransformer).

Proposed solution

I would suggest altering OnePasswordItem to look like:

apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
  name: <item_name> #this name will also be used for naming the generated kubernetes secret
spec:
  vault: "<vault_id_or_title>"
  item: "<item_id_or_title>"

...and the Deployment annotation could look like:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-example
  annotations:
    operator.1password.io/item-vault: "<vault_id_or_title>"
    operator.1password.io/item-item: "<item_id_or_title>" # This is a really bad name, but follows convention
    operator.1password.io/item-name: "<secret_name>"

One interesting side-effect of this decoupling, is that vault: or operator.1password.io/item-vault would be optional. It means that the Onepassword-Operator could be expanded to include a "default vault".

So for my use case: My stored OnePasswordItem and operator.1password.io/ annotations would include an item: or operator.1password.io/item-item, but when I deploy these configurations to staging, I'd merely set the "default vault" to be staging on my Onepassword-Operator. Then for production, I'd simply set the Onepassword-Operator's "default vault" to production. It's a single change and trivial to maintain.

Is there a workaround to accomplish this today?

The only option would be to use External Secrets in conjunction with staker/Reloader. Unfortunately, this comes at the expense of needing two different annotations (one for External Secrets and a second for Reloader).

References & Prior Work

See link above.

Hello!

I've added your request to our internal tracker. I can't make promises about implementation, but I wanted to make sure you knew we've seen your suggestion.

Thanks!

It's possible to use replacement in kustomize since https://github.com/kubernetes-sigs/kustomize/releases/tag/kustomize%2Fv4.1.3 to be able to change the vault id

Here's a direct link to the replacement documentation https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/replacements/

I use a config map to store the vault id

replacement-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
  name: replacement-config
  namespace: apps
data:
  vault_id: "YOUR VAULT ID"

with the following replacement

replacement.yaml

source:
  kind: ConfigMap
  name: replacement-config
  namespace: apps
  fieldPath: .data.vault_id
targets:
  - select:
      kind: OnePasswordItem
    fieldPaths:
      - spec.itemPath
    options:
      delimiter: "/"
      index: 1

and add the following lines into the kustomization.yaml


resources:
  - replacement-config.yaml

replacements:
  - path: replacement.yaml

Hey @rkr-kununu! 👋

Would the suggestion mentioned by @havard024 work for your case with Kustomize 4.1.3 or later? 🤔