Input Descriptors

Input Descriptors are the core building blocks of Presentation Exchange that enable verifiers to precisely articulate what credential data they need from holders. They form the foundation of Presentation Definitions in credential exchange workflows. They serve as detailed specifications for the credential information required during verification workflows, providing both the technical schema and the human-readable context for data requests.

What are Input Descriptors?

Input Descriptors define the specific credential data requirements a verifier needs from a holder to proceed with an interaction. They allow verifiers to:

  • Specify exactly which credential fields are needed
  • Define constraints on acceptable values
  • Set requirements for credential formats
  • Configure disclosure limitations to enhance privacy
  • Express the purpose for requesting specific information

Input Descriptors are designed to be both precise for machines to process and clear for humans to understand, serving as the bridge between technical verification requirements and meaningful user consent.

Why use Input Descriptors?

Input Descriptors solve several key challenges in decentralized identity verification:

  • Standardized requests: Create a consistent way to request specific credential data across different systems and credential formats
  • Precise targeting: Target exactly the data points needed while respecting privacy
  • Format flexibility: Work with various credential formats (VCs, JWTs, etc.) through a single request mechanism
  • Enhanced privacy: Support selective disclosure and data minimization principles
  • Clear expectations: Communicate to holders exactly what information is needed and why

Without Input Descriptors, credential verification would require custom, non-interoperable request formats or overly broad data sharing that compromises privacy.

Core Structure

An Input Descriptor is a JSON object with the following structure:

{
    "id": "employment_credential",
    "name": "Proof of Employment",
    "purpose": "We need to verify your current employment status",
    "format": {
        "jwt_vc": {
            "alg": ["ES256K", "EdDSA"]
        }
    },
    "group": ["A"],
    "constraints": {
        "limit_disclosure": "required",
        "fields": [
            {
                "path": ["$.type", "$.vc.type"],
                "filter": {
                    "type": "array",
                    "contains": {
                        "type": "string",
                        "pattern": "^EmploymentCredential$"
                    }
                }
            },
            {
                "path": ["$.credentialSubject.employmentStatus"],
                "filter": {
                    "type": "string",
                    "enum": ["Employed", "Full-time", "Part-time"]
                }
            }
        ]
    }
}

Required Properties

  • id: A unique identifier for the Input Descriptor
  • constraints: An object defining the requirements for acceptable credentials

Optional Properties

  • name: A human-readable name for the credential requirement
  • purpose: A description explaining why this information is being requested
  • format: Format-specific requirements for the credential (algorithms, proofs, etc.)
  • group: Identifiers that can be referenced in submission requirement rules

Field Constraints

The heart of an Input Descriptor is its constraints object, which defines what makes a credential acceptable for submission. The most important component is the fields array, which uses JSONPath expressions to target specific data within credentials.

Path Expressions

Path expressions use JSONPath to precisely target fields within a credential. For example:

"path": ["$.credentialSubject.dateOfBirth", "$.vc.credentialSubject.dateOfBirth"]

Multiple paths can be provided to account for different credential formats or structures. The system evaluates paths from left to right until a match is found.

Filters and Validation

Filters let you specify requirements for the values found at the specified paths using JSON Schema:

"filter": {
  "type": "string",
  "format": "date",
  "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
}

Filters can:

  • Validate data types
  • Check patterns with regular expressions
  • Ensure values are within specific ranges
  • Require values from an enumerated set
  • Apply complex validation rules with nested schemas

Optional Fields

Fields can be marked as optional using the optional property:

{
    "path": ["$.credentialSubject.phoneNumber"],
    "optional": true,
    "filter": {
        "type": "string"
    }
}

When a field is marked optional, the credential remains valid even if the specified path doesn't exist in the credential. However, if the path does exist, its value must still satisfy any filter requirements.

Limit Disclosure

The limit_disclosure property in the constraints object controls how much information the holder should share:

"constraints": {
  "limit_disclosure": "required",
  "fields": [...]
}

Options include:

  • required: The holder MUST only share the specific fields requested
  • preferred: The holder SHOULD limit disclosure to requested fields when possible
  • (omitted): No specific instruction for limiting disclosure

This feature is crucial for implementing data minimization and privacy protection.

JSONPath Expressions

Input Descriptors use JSONPath to locate and extract information from credentials. Understanding JSONPath is essential for creating effective descriptors.

Syntax Basics

The JSONPath syntax used in Input Descriptors follows these rules:

  • Expressions MUST begin with $, representing the root of the document
  • .property selects the named property from an object
  • [index] selects the indexed element from an array
  • * serves as a wildcard for properties or array indices

For example, to select a birthdate field that might be located in different places depending on the credential format:

"path": [
  "$.credentialSubject.birthDate",
  "$.vc.credentialSubject.birthDate",
  "$.claims.birthDate"
]

Common Patterns

Some common JSONPath patterns used in Input Descriptors include:

  • Type checking: $.type or $.vc.type to verify credential types
  • Issuer verification: $.issuer or $.vc.issuer to check credential source
  • Subject data: $.credentialSubject.fieldName to access specific claims
  • Nested data: $.credentialSubject.address.city for hierarchical information
  • Array elements: $.credentialSubject.qualifications[*].name for items in arrays

Format Requirements

Input Descriptors can specify which credential formats and cryptographic algorithms are acceptable through the format property:

"format": {
  "jwt_vc": {
    "alg": ["ES256K", "EdDSA"]
  },
  "ldp_vc": {
    "proof_type": ["Ed25519Signature2018"]
  }
}

This allows verifiers to:

  • Require specific credential formats (JWT, JSON-LD, etc.)
  • Specify acceptable cryptographic algorithms
  • Enforce particular proof types
  • Set format-specific requirements

The format requirements ensure that submitted credentials not only contain the right information but are also presented in a format the verifier can process and verify.

Advanced Features

Holder Binding

Input Descriptors can specify how the credential holder must be related to the credential subject through constraints:

"constraints": {
  "is_holder": [
    {
      "field_id": ["field1", "field2"],
      "directive": "required"
    }
  ]
}

Options include:

  • required: The credential MUST be bound to the holder
  • preferred: The credential SHOULD be bound to the holder when possible

Subject Binding

Similar to holder binding, subject binding ensures consistent subjects across multiple credentials:

"constraints": {
  "same_subject": [
    {
      "field_id": ["field1", "field2"],
      "directive": "required"
    }
  ]
}

This helps verify that multiple credentials refer to the same entity.

Predicates

Input Descriptors support predicate-based disclosure, which allows verifiers to request proof of a statement about data without seeing the actual data:

{
    "path": ["$.credentialSubject.age"],
    "filter": {
        "type": "integer",
        "minimum": 18
    },
    "predicate": "required"
}

With predicates, a holder can prove they meet a requirement (like being over 18) without revealing the exact value (their specific age).

Status Checking

For credentials with revocation or suspension capabilities, Input Descriptors can specify status checking requirements:

"constraints": {
  "statuses": {
    "active": {
      "directive": "required",
      "type": ["StatusList2021Entry"]
    },
    "suspended": {
      "directive": "disallowed",
      "type": ["StatusList2021Entry"]
    },
    "revoked": {
      "directive": "disallowed",
      "type": ["StatusList2021Entry"]
    }
  }
}

This ensures that credentials are in the appropriate status for acceptance.

Integration with Vidos Validator

In the Vidos ecosystem, Input Descriptors are primarily processed by the Validator service, which uses them to:

  1. Parse and interpret the requirements specified in Presentation Definitions
  2. Match presented credentials against the specified constraints
  3. Apply appropriate validation rules based on Input Descriptor requirements
  4. Implement privacy controls like selective disclosure when requested
  5. Enforce format-specific verification according to format properties

The Validator processes Input Descriptors to determine whether the credentials presented by a holder satisfy the verifier's requirements before allowing the interaction to proceed.

Best Practices

Effective Input Descriptor Design

When creating Input Descriptors:

  • Be explicit about purpose: Always include a clear purpose statement for each descriptor
  • Use multiple paths: Account for different credential formats with alternative paths
  • Prioritize performance: Order field checks with the most distinctive criteria first
  • Respect privacy: Use limit_disclosure when only specific fields are needed
  • Balance security and flexibility: Consider which requirements are truly necessary vs. preferred
  • Consider UX implications: More complex requirements may create friction for holders

Common Pitfalls

Avoid these common issues:

  • Overly restrictive paths: Requiring a specific structure that excludes valid credentials
  • Insufficient constraints: Not properly validating credential types or issuers
  • Missing alternative paths: Not accounting for format differences
  • Ignoring optional fields: Making all fields required when some should be optional
  • Format limitations: Unnecessarily restricting accepted credential formats

Examples

Basic Credential Type Verification

{
    "id": "basic_id_check",
    "name": "Government ID",
    "purpose": "We need to verify your identity",
    "constraints": {
        "fields": [
            {
                "path": ["$.type"],
                "filter": {
                    "type": "array",
                    "contains": {
                        "type": "string",
                        "pattern": "^GovernmentIDCredential$"
                    }
                }
            }
        ]
    }
}

Age Verification with Privacy

{
    "id": "age_verification",
    "name": "Age Verification",
    "purpose": "We need to verify you are over 21",
    "constraints": {
        "limit_disclosure": "required",
        "fields": [
            {
                "path": ["$.credentialSubject.birthDate"],
                "filter": {
                    "type": "string",
                    "format": "date"
                },
                "predicate": "required"
            }
        ]
    }
}

Complex Multi-Field Validation

{
    "id": "address_verification",
    "name": "Address Verification",
    "purpose": "We need to verify your residence in an eligible location",
    "constraints": {
        "fields": [
            {
                "path": ["$.type"],
                "filter": {
                    "type": "array",
                    "contains": {
                        "type": "string",
                        "pattern": "^AddressCredential$"
                    }
                }
            },
            {
                "path": ["$.credentialSubject.address.country"],
                "filter": {
                    "type": "string",
                    "enum": ["US", "CA"]
                }
            },
            {
                "path": ["$.credentialSubject.address.postalCode"],
                "filter": {
                    "type": "string",
                    "pattern": "^[0-9]{5}(-[0-9]{4})?$|^[A-Z][0-9][A-Z] [0-9][A-Z][0-9]$"
                }
            },
            {
                "path": ["$.credentialSubject.address.region"],
                "filter": {
                    "type": "string",
                    "not": {
                        "enum": ["HI", "AK"]
                    }
                }
            }
        ]
    }
}

Summary

Input Descriptors are the detailed building blocks of Presentation Definitions that enable precise, privacy-respecting credential verification. They allow verifiers to articulate exactly what data they need from holders while providing the contextual information holders need to make informed consent decisions.

Key benefits include:

  • Precise specification of required credential data
  • Support for various credential formats and structures
  • Enhanced privacy through selective disclosure
  • Clear communication of verification requirements
  • Standardized approach to credential verification

Through Input Descriptors, the Vidos platform enables detailed, interoperable verification workflows that balance security requirements with privacy considerations in a standardized way.

Further Resources