DSC icon indicating copy to clipboard operation
DSC copied to clipboard

Canonical properties for credentials

Open ThomasNieto opened this issue 1 month ago • 1 comments

Summary of the new feature / enhancement

As a user I would like canonical properties for credential fields so that resources use the same convention.

Proposed technical implementation details (optional)

Some example properties:

  • _username
  • _password
  • _token

_password and _token could be combined to be a generic that accounts for all types of secrets, maybe a _secret property.

ThomasNieto avatar Nov 19 '25 01:11 ThomasNieto

A few considerations:

  1. Some resources require multiple secrets of the same kind (such as credentials for authenticating to a service and a second credential being created).
  2. Rather than separate properties for username and password, I would prefer a _credential canonical property that defines the identity and secret.
  3. To address the first item, we should probably define the _credential and _secret canonical properties as well as the ^_(?<prefix>[a-z][a-zA-Z]*)Credential and ^_(?<prefix>[a-z][a-zA-Z]*)Secret canonical pattern properties.
  4. We can't provide much in the way of validation for the actual string values in these canonical properties because that varies so widely between implementations. We can show resource authors how to extend the definition usefully, such as adding annotation keywords for documentation and additional validation, like applying a pattern to the identity field in the _credential property.

The schemas for this would look something like:

_secret canonical property schema
$schema:   https://json-schema.org/draft/2020-12/schema
$id:       https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
title:     Secret
writeOnly: true
type:      string
examples:
  - $comment: >-
      This example resource instance schema defines the `_secret` canonical property.
    title: MyResource
    type:  object
    required: [name, _secret]
    properties:
      name:
        type: string
      _secret:
        $ref: https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
  - $comment: >-
      This example resource instance schema defines the `_fooApiSecret` and `_barApiSecret`
      canonical pattern properties.
    title: MyResource
    type:  object
    required: [name, _fooApiSecret, _barApiSecret]
    properties:
      name:
        type: string
      _fooApiSecret:
        $ref: https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
      _barApiSecret:
        $ref: https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
_credential canonical property schema
$schema:              https://json-schema.org/draft/2020-12/schema
$id:                   https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
title:                 Credential
writeOnly:             true
type:                  object
unevaluatedProperties: false
minProperties:         1 # Must define either or both identity/secret
properties:
  identity:
    title: Credential identity
    type:  string
  secret:
    title: Credential secret
    $ref: https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
examples:
  - $comment: >-
      This example resource instance schema defines the `_credential` canonical property. It
      extends the definition for the canonical property to restrict the characters in the
      identity.
    $schema: https://json-schema.org/draft/2020-12/schema
    $id:     https://contoso.com/schemas/example/resource.json
    type:    object
    required: [name, _credential]
    properties:
      name: { type: string }
      _credential:
        $ref: https://aka.ms/dsc/schemas/v3/resource/properties/credential.json
        title: Service authentication credential
        description: Authenticates to the service.
        required: [identity, secret]
        properties:
          identity:
            title: Service authentication identity
            description: >-
              Defines the identity to authenticate with. Must be a string of
              alphanumeric characters and underscores between 5 and 15 characters
              long.
            pattern: ^\w+$
            minLength: 5
            maxLength: 15

  - $comment: >-
      This example resource instance schema defines the `_fooCredential` and `_barCredential`
      canonical pattern properties without overriding.
    title: MyResource
    type:  object
    required: [name, _fooApiCredential, _barApiCredential]
    properties:
      name:
        type: string
      _fooApiCredential:
        $ref: https://aka.ms/dsc/schemas/v3/resource/properties/secret.json
      _barApiCredential:
        $ref: https://aka.ms/dsc/schemas/v3/resource/properties/secret.json

Thinking about this and doing some local testing, I think this model does broadly work and would enable us to always mark these canonical properties (and canonical pattern properties) as secret internally, to limit the risk of leaking secrets. What we can't currently do without an extended vocabulary is explicitly indicate that these values are secret in the JSON Schema, except by our convention.

When we define the extended vocabulary, we should probably define a keyword like x-dsc-isSecret or x-dsc-isSensitive to clearly indicate that a value should always be redacted. Then, even for values that don't map to these canonical properties, DSC can either require the user pass the values as secrets or redact the values regardless of whether the user passed them as a secret. The latter is probably helpful for sensitive/secret values whose subschema defines the keyword but aren't objects or strings (and so the internal data model inherited from ARM doesn't have a way to automatically redact those values).

michaeltlombardi avatar Nov 19 '25 15:11 michaeltlombardi