Restrict policies parameter values when creating entities using splat in "allowed_parameters"

According to the fine-grained control section of the policy concept page, you can restrict the values of parameters using allowed_parameters.

In addition, you can use a splat (*) to enable globbing for the parameter values as seen in this example:

# Only allow a parameter named "bar" with a value starting with "foo-*".
path "secret/foo" {
  capabilities = ["create"]
  allowed_parameters = {
    "bar" = ["foo-*"]
  }
}

My goal is to restrict the possible values that can be used when creating entities through the create entity API. I figured I could use allowed_parameters to do this; however, this doesn’t seem to be the case.

A token with the following policy:

path "/identity/entity" {
  capabilities = ["update"]
  allowed_parameters = {
    "policies" = [
      ["hello*"]
    ]
  }
}

will not allow the token to create an entity with the policy helloworld:

$ curl \
    --header "X-Vault-Token: $vault_token" \
    --request POST \
    --data '{ "policies": ["helloworld"] }' \
    http://127.0.0.1:8200/v1/identity/entity
{"errors":["1 error occurred:\n\t* permission denied\n\n"]}

However, changing the specified policy in the create entity request to hello* will allow the operation:

$ curl \
    --header "X-Vault-Token: $vault_token" \
    --request POST \
    --data '{ "policies": ["hello*"] }' \
    http://127.0.0.1:8200/v1/identity/entity
{"request_id":"7eea7fd2-d5d0-2f0a-c79d-675a251d2839","lease_id":"","renewable":false,"lease_duration":0,"data":{"aliases":null,"id":"d0ecc9e1-874d-15d6-d2b7-97bea52b414e","name":"entity_b3f7e00a"},"wrap_info":null,"warnings":null,"auth":null}

I figured that the splat (*) was not behaving like I thought it would and only worked on string values, whereas policies takes an array value.
Is my conclusion true? If so, is there a way to reach my goal?

That does sound accurate.

No, there is no way to do this safely with allowed_parameters.

And, the reason is that Vault parameters that take multiple values, are set up to take either a JSON array, or a JSON string that is split on commas.

Because of this, even if you write a policy that says:

allowed_parameters = { "policies" = ["foo-*"] }

this policy will allow someone sending a policies value of foo-bar,some-other-super-high-privileged-policy and break your intended security controls!

Basically, the allowed_parameters support in Vault is completely unsuitable for working with any fields that take multiple values.