1Password / terraform-provider-onepassword

Use the 1Password Terraform Provider to reference, create, or update items in your 1Password Vaults.
https://developer.1password.com/docs/terraform/
MIT License
322 stars 45 forks source link

Unicode encoded characters should be decoded when retrieved by data #188

Closed vponoikoait closed 3 months ago

vponoikoait commented 3 months ago

Your environment

Terraform Provider Version: 2.0.0

Connect Server Version: using cloud version

CLI Version: 2.24.0/2.29.0

OS: macOS Sonoma 14.5

Terraform Version: v1.8.0 / v1.9.1 on darwin_arm64

What happened?

data.onepassword_item when I am trying to return my string 'my>string' does provide me with a 'my\u003estring' output, which includes unicode encoded character. Shouldn't decode cases be covered on the side of the provider?

What did you expect to happen?

I expect data.onepassword_item return to me fully decoded string

Steps to reproduce

  1. Create Item in your vault within any section with the special characters and try to retrieve it
    data "onepassword_item" "this" {
    vault = data.onepassword_vault.this.name
    title = "my-title"
    }
  2. Check item value for section field value. For example, with
    resource "local_file" "for" {
    content  = jsonencode([ for secret in data.onepassword_item.this.section[0].field: "${secret["label"]} = ${(secret["value"])}"])
    filename = "for.json"
    }

    Or check tfstate directly

    Notes & Logs

vponoikoait commented 3 months ago

I've tried it with CLI ( to follow how provider does it ) I can see that issue for my special character persists only when

export OP_FORMAT=json With export OP_FORMAT=human-readable I can see no issue As this may be considered a problem of API of OnePassword itself, still there's a need of solution/hack somewhere and fastest would be likely to have it inside of the provider Somewhere here -> https://github.com/1Password/terraform-provider-onepassword/blob/main/internal/onepassword/cli/op.go#L99

edif2008 commented 3 months ago

Hey @vponoikoait!

Thank you for reaching out to us!

It seems that you're experiencing this due to the use of the jsonencode function in your Terraform configuration. According to the documentation of this function:

When encoding strings, this function escapes some characters using Unicode escape sequences: replacing <, >, &, U+2028, and U+2029 with \u003c, \u003e, \u0026, \u2028, and \u2029. This is to preserve compatibility with Terraform 0.11 behavior.

The value obtained from the 1Password item data source has the string as is, with the special characters not encoded.

A solution that can solve your issue is to fetch the value from the item without using jsonencode. 😄

vponoikoait commented 3 months ago

I will also post this here: https://github.com/hashicorp/terraform/issues/26110 as related And possibly way of what I've to achieve and how I did later if I won't forget

vponoikoait commented 3 months ago

If somebody will run into the same issue Initially I've run into need of using secrets manager (1Password to secrets manager) where mainly suggested option is jsonencode for aws_secretsmanager_secret_version secret_string argument -> https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/secretsmanager_secret_version#key-value-pairs I've worked around over it with the usage of templatefile

locals { 
  secrets = [
    for secret in data.onepassword_item.this.section[0].field :
    {
      label = secret["label"]
      value = secret["value"]
    }
  ]
  secrets_json = templatefile("${path.cwd}/secret.template.json", { secrets = local.secrets })
}

secret.template.json

{
%{ for i, secret in secrets ~}
"${secret.label}": "${secret.value}"%{ if i < length(secrets) - 1 },%{ endif }
%{ endfor ~}
}

So now I can do

resource "aws_secretsmanager_secret_version" "example" {
  secret_id     = aws_secretsmanager_secret.example.id
  secret_string = local.secrets_json
}

There may be more optimized ways of doing it, though, finding this workaround to be suitable for use case