Gramática da política de liberação de chave segura do Azure Key Vault

Este artigo documenta uma gramática EBNF simplificada para a política de liberação de chave segura, que é modelada no Azure Policy. Para obter um exemplo completo de uma política de liberação de chave segura, consulte a política de liberação de chave de VM confidencial.

(* string and number from JSON *)
value =
  string |
  number |
  "true" |
  "false";

(* The operators supported for claim value comparison *)
operator =
  "equals:" |
  "notEquals:" |
  "less:" |
  "lessOrEquals:" |
  "greater:" |
  "greaterOrEquals:" |
  "exists:";

(* A JSON condition that evaluates the value of a claim *)
claim_condition =
  "{" "claim:", string "," operator, ":", value "}";

(* A JSON condition requiring any of the listed conditions to be true *)
anyof_condition =
  "{" "anyof:", condition_array "}";

(* A JSON condition requiring all of the listed conditions to be true *)
allof_condition =
  "{" "allof:", condition_array "}";

(* A condition is any of the allowed condition types *)
condition =
  claim_condition |
  anyof_condition |
  allof_condition;

(* A list of conditions, one is required *)
condition_list =
  condition { "," condition };

(* An JSON array of conditions *)
condition_array =
  "[" condition_list "]";

(* A JSON authority with its conditions *)
authority =
  "{" "authority:", string "," ( anyof_condition | allof_condition );

(* A list of authorities, one is required *)
authority_list =
  authority { "," authority_list };

(* A policy is an anyOf selector of authorities *)
policy = 
  "{" "version: \"1.0.0\"", "anyOf:", "[" authority_list "]" "}";

Condição de declaração

Uma Condição de Declaração é um objeto JSON que identifica um nome de declaração, uma condição de correspondência e um valor, por exemplo:

{ 
  "claim": "<claim name>", 
  "equals": <value to match>
} 

Na primeira iteração, a única condição permitida é "igual a", mas iterações futuras podem permitir outros operadores semelhantes ao Azure Policy (confira a seção sobre Condições). Se uma declaração especificada não estiver presente, a condição dela será considerada como não atendida.

Os nomes de declaração permitem a "notação de pontos", para habilitar a navegação de objeto do JSON, por exemplo:

{ 
  "claim": "object.object.claim", 
  "equals": <value to match>
}

Atualmente, não há suporte para as especificações de matriz. De acordo com a gramática, objetos não são admitidos como valores de correspondência.

Condições AnyOf e AllOf

Objetos das condições AnOf e AllOf permitem a modelagem dos operadores OR e AND. Para o AnyOf, se qualquer uma das condições fornecidas for verdadeira, a condição será atendida. Para o AllOf, todas as condições precisam ser verdadeiras.

Os exemplos são mostrados abaixo. Na primeira, AllOf requer que todas as condições sejam atendidas:

{
  "allOf":
  [
    { 
      "claim": "<claim_1>", 
      "equals": <value_1>
    },
    { 
      "claim": "<claim_2>", 
      "equals": <value_2>
    }
  ]
}

Significado (claim_1 == value_1) && (claim_2 == value_2).

Neste exemplo, AnyOf requer que qualquer condição corresponda:

{
  "anyOf":
  [
    { 
      "claim": "<claim_1>", 
      "equals": <value_1>
    },
    { 
      "claim": "<claim_2>", 
      "equals": <value_2>
    }
  ]
}

Isso significa (claim_1 == value_2) || (claim_2 == value_2)

Os objetos de condição AnyOf e AllOf podem ser aninhados:

  "allOf":
  [
    { 
      "claim": "<claim_1>", 
      "equals": <value_1>
    },
    {
      "anyOf":
      [
        { 
          "claim": "<claim_2>", 
          "equals": <value_2>
        },
        { 
          "claim": "<claim_3>", 
          "equals": <value_3>
        }
      ]
    }
  ]

Ou:

{
  "allOf":
  [
    { 
      "claim": "<claim_1>", 
      "equals": <value_1>
    },
    {
      "anyOf":
      [
        { 
          "claim": "<claim_2>", 
          "equals": <value_2>
        },
        {
          "allOf":
          [
            { 
              "claim": "<claim_3>", 
              "equals": <value_3>
            },
            { 
              "claim": "<claim_4>", 
              "equals": <value_4>
            }
          ]
        }
      ]
    }
  ]
}

Autoridade de liberação de chaves

As condições são coletadas em instruções de autoridade e combinadas:

{
  "authority": "<issuer>",
  "allOf":
  [
    { 
      "claim": "<claim_1>", 
      "equals": <value_1>
    }
  ]
}

Em que:

  • authority: identificador da autoridade que está fazendo as declarações. Esse identificador funciona da mesma maneira que a declaração iss em um Token Web JSON. Ele faz referência indiretamente a uma chave que assina a Declaração de Ambiente.
  • AllOf: uma ou mais condições de declaração que identificam declarações e valores que precisam ser satisfeitos na instrução de declaração de ambiente para que a política de versão seja bem-sucedida. AnyOf também é permitido. No entanto, ambos não são permitidos juntos.

Política de liberação de chaves

A política de liberação é uma condição AnyOf que contém uma matriz de autoridades-chave:

{
  "anyOf":
  [
    {
      "authority": "my.attestation.com",
      "allOf":
      [
        { 
          "claim": "mr-signer", 
          "equals": "0123456789"
        }
      ]
    }
  ]
}

Política de liberação de chave de codificação

Como a política de liberação de chave é um documento JSON, ela é codificada quando em solicitações e em respostas ao AKV para evitar a necessidade de descrever a linguagem completa nas definições do Swagger.

A codificação é a seguinte:

{
  "contentType": "application/json; charset=utf-8",
  "data": "<BASE64URL(JSON serialization of policy)>"
}

Instrução de declaração do ambiente

Uma Declaração de Ambiente é uma declaração assinada, no formato de Token Web JSON, de uma autoridade confiável. Ela contém pelo menos uma chave de criptografia de chave e uma ou mais declarações sobre o ambiente de destino (por exemplo, tipo TEE, distribuidor, versão) que são corresponderes à política de liberação de chaves. A chave de criptografia de chave é uma chave RSA pública protegida e de propriedade do ambiente de execução de destino que é usado para a exportação de chaves. Ela deve aparecer na declaração de chaves TEE (x-ms-runtime/chaves). Essa declaração é um objeto JSON que representa um conjunto de Chaves Web JSON. No JWKS, uma das chaves deve atender aos requisitos para uso como uma chave de criptografia (key_use é "enc" ou key_ops contém "encrypt"). A primeira chave adequada é escolhida.

O Key Vault e os Requisitos de Token de Atestado de HSM Gerenciado

O Azure Key Vault Premium e o Managed HSM Secure Key Release foram projetados junto com o Serviço de Atestado do Microsoft Azure, mas podem funcionar com tokens de qualquer servidor de atestado se estiverem em conformidade com a estrutura de token esperada, oferecerem suporte à conexão OpenID e tiverem as declarações esperadas. Atualmente, a DigiCert é a única CA pública em que o Azure Key Vault Premium e o Managed HSM confiam para certificados de assinatura de token de atestado.

O conjunto completo de requisitos é:

  • Declaração iss que identifica que o emissor é necessário e que é comparada com a política SKR na chave que está sendo solicitada.

    • O emissor deve ser compatível com metadados do OpenID Connect por meio de um certificado com raiz na AC DigiCert.

    • Nos Metadados do OpenID Connect, a declaração jwks_uri é necessária e deve ser resolvida em um Conjunto de Chaves Web JSON (JWKS), em que cada JWK no conjunto deve conter kid, kty e uma matriz X5c de certificados de assinatura.

  • A declaração x-ms-runtime é necessária como um objeto JSON que contém:

    • Uma matriz de Chaves Web JSON denominadas chaves que representam as chaves mantidas pelo ambiente atestado. As chaves devem ser formato JWK simples ou matriz x5c (a primeira chave é tomada como a chave de assinatura e seu filho deve corresponder a uma chave de assinatura nos metadados do OpenId Connect).

    • O filho é obrigatório.

    • Uma delas deve ser uma chave RSA.

    • Marcado com key_use de criptografia ou uma matriz key_ops que contém a operação Criptografar.

Para obter um token de exemplo, consulte Exemplos de um token de Atestado do Azure.