From ca41e9796aaa5b692b30591c60cec4b316c0ee3f Mon Sep 17 00:00:00 2001 From: tmanninger Date: Mon, 19 Dec 2022 08:25:34 +0100 Subject: [PATCH 1/3] Add parameter allowed_metadata_extensions to resource vault_cert_auth_backend_role --- vault/resource_cert_auth_backend_role.go | 21 +++++++++++++++++++ vault/resource_cert_auth_backend_role_test.go | 19 +++++++++++++---- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/vault/resource_cert_auth_backend_role.go b/vault/resource_cert_auth_backend_role.go index c70efd92c0..6085fe9ce8 100644 --- a/vault/resource_cert_auth_backend_role.go +++ b/vault/resource_cert_auth_backend_role.go @@ -29,6 +29,7 @@ const ( fieldOCSPQueryAllServers = "ocsp_query_all_servers" fieldOCSPServersOverride = "ocsp_servers_override" fieldRequiredExtensions = "required_extensions" + fieldAllowedMetadataExtensions = "allowed_metadata_extensions" ) var ( @@ -46,6 +47,7 @@ var ( fieldAllowedURISans, fieldOCSPServersOverride, fieldRequiredExtensions, + fieldAllowedMetadataExtensions, } certAuthBoolFields = []string{ fieldOCSPEnabled, @@ -182,6 +184,14 @@ func certAuthBackendRoleResource() *schema.Resource { "successful OCSP response, query all servers and consider the " + "certificate valid only if all servers agree.", }, + fieldAllowedMetadataExtensions: { + Type: schema.TypeSet, + Optional: true, + Description: "A array of oid extensions.", + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, } addTokenFields(fields, &addTokenFieldsConfig{}) @@ -385,6 +395,17 @@ func certAuthResourceRead(_ context.Context, d *schema.ResourceData, meta interf schema.HashString, []interface{}{})) } + // Vault sometimes returns these as null instead of an empty list. + if resp.Data["allowed_metadata_extensions"] != nil { + d.Set("allowed_metadata_extensions", + schema.NewSet( + schema.HashString, resp.Data["allowed_metadata_extensions"].([]interface{}))) + } else { + d.Set("allowed_metadata_extensions", + schema.NewSet( + schema.HashString, []interface{}{})) + } + if err := d.Set("allowed_organizational_units", resp.Data["allowed_organizational_units"]); err != nil { return diag.FromErr(err) } diff --git a/vault/resource_cert_auth_backend_role_test.go b/vault/resource_cert_auth_backend_role_test.go index 2d214ea7ca..8eb615a720 100644 --- a/vault/resource_cert_auth_backend_role_test.go +++ b/vault/resource_cert_auth_backend_role_test.go @@ -82,6 +82,11 @@ func TestCertAuthBackend(t *testing.T) { allowedOrgUnits := []string{"foo", "baz"} + allowedMetadataExtensions := []string{ + "1.3.6.1.4.1.34380.1.2.1", + "1.3.6.1.4.1.34380.1.2.2", + } + resourceName := "vault_cert_auth_backend_role.test" resource.Test(t, resource.TestCase{ PreCheck: func() { testutil.TestAccPreCheck(t) }, @@ -89,7 +94,7 @@ func TestCertAuthBackend(t *testing.T) { CheckDestroy: testCertAuthBackendDestroy, Steps: []resource.TestStep{ { - Config: testCertAuthBackendConfig_basic(backend, name, testCertificate, allowedNames, allowedOrgUnits), + Config: testCertAuthBackendConfig_basic(backend, name, testCertificate, allowedNames, allowedOrgUnits, allowedMetadataExtensions), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resourceName, "backend", backend), resource.TestCheckResourceAttr(resourceName, "name", name), @@ -100,6 +105,9 @@ func TestCertAuthBackend(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "allowed_organizational_units.#", "2"), resource.TestCheckTypeSetElemAttr(resourceName, "allowed_organizational_units.*", "foo"), resource.TestCheckTypeSetElemAttr(resourceName, "allowed_organizational_units.*", "baz"), + resource.TestCheckResourceAttr(resourceName, "allowed_organizational_units.#", "2"), + resource.TestCheckResourceAttr(resourceName, "allowed_metadata_extensions.0", "1.3.6.1.4.1.34380.1.2.1"), + resource.TestCheckResourceAttr(resourceName, "allowed_metadata_extensions.1", "1.3.6.1.4.1.34380.1.2.2"), testCertAuthBackendCheck_attrs(resourceName, backend, name), ), }, @@ -113,6 +121,7 @@ func TestCertAuthBackend(t *testing.T) { resource.TestCheckResourceAttr(resourceName, "token_max_ttl", "0"), resource.TestCheckResourceAttr(resourceName, "allowed_names.#", "2"), resource.TestCheckResourceAttr(resourceName, "allowed_organizational_units.#", "0"), + resource.TestCheckResourceAttr(resourceName, "allowed_metadata_extensions.#", "0"), testCertAuthBackendCheck_attrs(resourceName, backend, name), ), }, @@ -225,6 +234,7 @@ func testCertAuthBackendCheck_attrs(resourceName, backend, name string) resource "allowed_email_sans": "allowed_email_sans", "allowed_uri_sans": "allowed_uri_sans", "allowed_organizational_units": "allowed_organizational_units", + "allowed_metadata_extensions": "allowed_metadata_extensions", "required_extensions": "required_extensions", "certificate": "certificate", } @@ -241,7 +251,7 @@ func testCertAuthBackendCheck_attrs(resourceName, backend, name string) resource VaultAttr: v, } switch k { - case TokenFieldPolicies, "allowed_names", "allowed_organizational_units": + case TokenFieldPolicies, "allowed_names", "allowed_organizational_units", "allowed_metadata_extensions": ta.AsSet = true } @@ -252,7 +262,7 @@ func testCertAuthBackendCheck_attrs(resourceName, backend, name string) resource } } -func testCertAuthBackendConfig_basic(backend, name, certificate string, allowedNames, allowedOrgUnits []string) string { +func testCertAuthBackendConfig_basic(backend, name, certificate string, allowedNames, allowedOrgUnits []string, allowedMetadataExtensions []string) string { config := fmt.Sprintf(` resource "vault_auth_backend" "cert" { @@ -271,8 +281,9 @@ EOF token_max_ttl = 600 token_policies = ["test_policy_1", "test_policy_2"] allowed_organizational_units = %s + allowed_metadata_extensions = %s } -`, backend, name, certificate, util.ArrayToTerraformList(allowedNames), util.ArrayToTerraformList(allowedOrgUnits)) +`, backend, name, certificate, util.ArrayToTerraformList(allowedNames), util.ArrayToTerraformList(allowedOrgUnits), util.ArrayToTerraformList(allowedMetadataExtensions)) return config } From 390dcea470641628d1b0ca2ad9b6021425f2ec5f Mon Sep 17 00:00:00 2001 From: tmanninger Date: Tue, 20 Dec 2022 10:40:18 +0100 Subject: [PATCH 2/3] Add doc --- website/docs/r/cert_auth_backend_role.html.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/website/docs/r/cert_auth_backend_role.html.md b/website/docs/r/cert_auth_backend_role.html.md index d78655b13a..a756d99301 100644 --- a/website/docs/r/cert_auth_backend_role.html.md +++ b/website/docs/r/cert_auth_backend_role.html.md @@ -56,6 +56,9 @@ The following arguments are supported: * `allowed_organizational_units` - (Optional array: []) Allowed organization units for authenticated client certificates. +* `allowed_metadata_extensions` - (Optional array: []) Allowed oid extensions. Upon successful authentication, + these extensions will be added as metadata if they are present in the certificate. + * `required_extensions` - (Optional array: []) TLS extensions required on client certificates From 8541c12d2a22a937ddc1c343b63b786429c5d45d Mon Sep 17 00:00:00 2001 From: Ferenc Kovacs Date: Thu, 20 Mar 2025 02:40:47 +0100 Subject: [PATCH 3/3] feat: add CHANGELOG entry --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 784561dd54..0943eed5a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,6 +28,7 @@ FEATURES: * GCP Auth/Secrets ([#2427](https://github.com/hashicorp/terraform-provider-vault/pull/2427)) * Add new resource `vault_pki_secret_backend_config_auto_tidy` to set PKI automatic tidy configuration [#1934](https://github.com/hashicorp/terraform-provider-vault/pull/1934) * Add support for cross-account management of static roles in AWS Secrets: ([#2413](https://github.com/hashicorp/terraform-provider-vault/pull/2413)) +* Add support for whitelisting certificate extensions with `allowed_metadata_extensions` in `vault_cert_auth_backend_role`: ([#2436](https://github.com/hashicorp/terraform-provider-vault/pull/2436)) BUGS: