---
id: dcql-basic-credential-query-with-trusted-authority
title: "DCQL: Trusted Authorities"
hide_title: false
description: DCQL credential query filtered by trusted authorities (EU Trust List, EBSI, OpenID Federation) using iGrant.io Digital Wallets.
sidebar_label: Trusted Authorities
keywords: [DCQL, trusted authorities, EU Trust List, EBSI, OpenID Federation, credential query, OpenID4VP, EUDI Wallet, trust framework]
slug: /dcql-basic-credential-query-with-trusted-authority/
---

> **Build this with an AI coding agent.** Install the iGrant.io Agent Skills, then ask your agent to build the integration:
>
> ```bash
> npx skills add L3-iGrant/skills
> ```
>
> This page maps to the `igrantio-dcql-trusted-authority` skill. Install just that one with:
>
> ```bash
> npx skills add L3-iGrant/skills -s igrantio-dcql-trusted-authority
> ```


import { ApiKeyManager } from "@site/src/components/ApiKeyManager";
import DcqlStepTemplate from "@site/src/components/DCQL/DcqlStepTemplate";

The `trusted_authorities` field in a DCQL query allows a verifier to restrict accepted credentials to those issued by specific trust anchors.

**Scenario:** A verifier requests a University Degree credential, accepting it only if issued by an authority in the EU Trust List, EBSI, or an OpenID Federation trust anchor.

For the underlying DCQL query, diagram and video walkthrough, see the **“Basic credential query with trusted authority”** use case in our [DCQL concepts article](/concepts/eudi-wallet-dcql-openid4vp-business-wallet-payments/#241-use-case-basic-credential-query-with-trusted-authority).

![Fig 01: Require a University Degree credential, only if issued by an authority listed in the trusted list.](../cDocs/articles/dcql-images/fig-01-dcql-eudi-wallet-university-degree-trusted-authority.png)

## Step 1: Get the API Key (Issuer Admin)

To obtain your API key, please contact [support@igrant.io](mailto:support@igrant.io?subject=Request%20API%20Key). Once you have received your API key, enter it in the field below and click the **Set API Key** button to save it for future use.

<ApiKeyManager />

## Step 2: Create Credential Definitions (Issuer Admin)

To create a credential definition, run the code block below using the **Run** button. Alternatively, you can manually copy the code block and use it in the body of the API request available [here](https://docs.igrant.io/docs/openid4vc-api/config-create-digital-wallet-open-id-credential-definition).

> Note: The `kid` value is mandatory with trust anchor `x509`. To obtain the `kid` value for the respective organisation use the API available [here](https://docs.igrant.io/docs/openid4vc-api/config-read-digital-wallet-open-id-organisation-identifier).

From the API response, copy the `credentialDefinitionId` and `id` value from the `credentialDefinitions` array for use in the Step 3.

### Aegean University Degree - Master's (Issuer Admin)

Use this step to create the credential definition for the Aegean University Master's degree that is present in the EWC Trust List and trust anchor `x509`.

<DcqlStepTemplate
  endpointPath="/v2/config/digital-wallet/openid/sdjwt/credential-definition"
  method="POST"
  initialJsonData={{
    label: "UAegean University Degree (Masters)",
    trustAnchor: "x509",
    version: "version_01",
    kid: "<kid>",
    enforceWUA: true,
    credentialDefinitions: [
      {
        credentialFormat: "dc+sd-jwt",
        vct: "UniversityDegree",
        claims: {
          claims: [
            { limitDisclosure: true, mandatory: true, path: ["name"] },
            { limitDisclosure: true, mandatory: true, path: ["registrationNumber"] },
            { limitDisclosure: true, mandatory: true, path: ["dateOfBirth"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject1"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject2"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject3"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject4"] },
          ],
        },
        display: {
          name: "UAegean University Degree (Masters)",
          description: "UAegean University's Master's degree credential",
        },
      },
    ],
  }}
/>

### Aegean University Degree - Bachelor's (Issuer Admin)

This step creates the credential definition for the Aegean University Bachelor's degree, also present in the EWC Trust List and trust anchor `x509`.

<DcqlStepTemplate
  endpointPath="/v2/config/digital-wallet/openid/sdjwt/credential-definition"
  method="POST"
  initialJsonData={{
    label: "UAegean University Degree (Bachelors)",
    trustAnchor: "x509",
    version: "version_01",
    kid: "<kid>",
    enforceWUA: true,
    credentialDefinitions: [
      {
        credentialFormat: "dc+sd-jwt",
        vct: "UniversityDegree",
        claims: {
          claims: [
            { limitDisclosure: true, mandatory: true, path: ["name"] },
            { limitDisclosure: true, mandatory: true, path: ["registrationNumber"] },
            { limitDisclosure: true, mandatory: true, path: ["dateOfBirth"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject1"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject2"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject3"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject4"] },
          ],
        },
        display: {
          name: "UAegean University Degree (Bachelors)",
          description: "UAegean University's Bachelor's degree credential",
        },
      },
    ],
  }}
/>

### ABC University Degree - Bachelor's (Issuer Admin)

In this step you create the credential definition for a Bachelor's degree issued by ABC University, Australia. This university is **not** in the EWC Trust List, so the trust anchor is a `did:key`.

<DcqlStepTemplate
  endpointPath="/v2/config/digital-wallet/openid/sdjwt/credential-definition"
  method="POST"
  initialJsonData={{
    label: "ABC University (Australia) (Bachelors)",
    trustAnchor: "did:key",
    version: "version_01",
    credentialDefinitions: [
      {
        credentialFormat: "dc+sd-jwt",
        vct: "UniversityDegree",
        claims: {
          claims: [
            { limitDisclosure: true, mandatory: true, path: ["name"] },
            { limitDisclosure: true, mandatory: true, path: ["registrationNumber"] },
            { limitDisclosure: true, mandatory: true, path: ["dateOfBirth"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject1"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject2"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject3"] },
            { limitDisclosure: true, mandatory: true, path: ["subjects", "subject4"] },
          ],
        },
        display: {
          name: "ABC University (Australia) (Bachelors)",
          description:
            "ABC University (Australia) Bachelor's degree credential",
        },
      },
    ],
  }}
/>

## Step 3: Issue and Receive Credential (Issuer/Holder)

The holder of the wallet submits a request for the issuance of a credential by executing the JSON code block below using the **Run** button in the `InTime` issuance mode. For each credential type (UAegean University Degree (Master's), UAegean University Degree (Bachelor's), and ABC University (Bachelor's), replace `<credentialDefinitionId>` and `<id>` with the actual values obtained from Step 2, and run the request separately for each credential. Alternatively, you may use the API available [here](https://docs.igrant.io/docs/openid4vc-api/config-digital-wallet-open-id-issue-credential).

After receiving the response, toggle the provided button to dynamically generate a QR code. The EUDI Wallet/Holder can then accept the credential offer using the [Data Wallet](https://www.igrant.io/datawallet.html) (or any other EU Digital Identity Wallet) by either scanning the QR code or directly accessing the credential offer on their mobile device (e.g. via a browser).

<DcqlStepTemplate
  endpointPath="/v2/config/digital-wallet/openid/sdjwt/credential/issue"
  method="POST"
  initialJsonData={{
    issuanceMode: "InTime",
    credentialDefinitionId: "<credentialDefinitionId>",
    userPin: "",
    credentials: [
      {
        id: "<id>",
        claims: {
          name: "Alice Andersson",
          registrationNumber: "SE-2020-000123",
          dateOfBirth: "1993-04-12",
          subjects: {
            subject1: "Computer Science",
            subject2: "Data Privacy and GDPR",
            subject3: "Distributed Systems",
            subject4: "Digital Identity and Wallets",
          },
        },
      },
    ],
  }}
  extractQrValue={(result) => result?.credentialHistory?.credentialOffer || ""}
/>

To receive and accept the credential via API. First, use the `credentialOffer` to call the [Receive Credential API](https://docs.igrant.io/docs/openid4vc-api/config-receive-digital-wallet-open-id-credential/). Once you have the response, copy the `credentialId` and provide it at [Accept Credential API](https://staging-docs.igrant.io/docs/openid4vc-api/config-accept-digital-wallet-open-id-credential/) to accept the credential.

## Step 4: Create Presentation Definition (Verifier Admin)

To create a presentation definition for requesting proof, you can run the code block below using the **Run** button. Alternatively, you can manually copy the code block and use it in the body of the API request provided [here](/docs/openid4vc-api/config-digital-wallet-open-id-presentation-definition).

> Note: The `kid` value is mandatory with trust anchor `x509`. To obtain the `kid` value for the respective organisation use the API available [here](https://docs.igrant.io/docs/openid4vc-api/config-read-digital-wallet-open-id-organisation-identifier).

- Create a Presentation Definition by executing the code block below.

<DcqlStepTemplate
  endpointPath="/v2/config/digital-wallet/openid/sdjwt/presentation-definition"
  method="POST"
  initialJsonData={{
    label: "Basic Credential Query with trusted authority",
    trustAnchor: "x509",
    kid: "<kid>",
    dcqlQuery: {
      credentials: [
        {
          id: "UniversityDegreeCredential",
          format: "dc+sd-jwt",
          meta: {
            vct_values: ["UniversityDegree"],
          },
          claims: [
            {
              path: ["name"],
            },
            {
              path: ["registrationNumber"],
            },
            {
              path: ["dateOfBirth"],
            },
            {
              path: ["subjects", "subject1"],
            },
            {
              path: ["subjects", "subject2"],
            },
            {
              path: ["subjects", "subject3"],
            },
            {
              path: ["subjects", "subject4"],
            },
          ],
          require_cryptographic_holder_binding: true,
          trusted_authorities: [
            {
              type: "etsi_tl",
              values: [
                "https://raw.githubusercontent.com/EWC-consortium/ewc-trust-list/refs/heads/main/EWC-TL.xml",
              ],
            },
          ],
        },
      ],
    },
  }}
/>

Once a presentation definition has been created, the `presentationDefinitionId` can be reused to verify multiple credentials (Step 5).

## Step 5: Create Verification Request (Verifier/Relying Party)

To create the verification request, execute the code block below using the **Run** button. Alternatively, you can manually copy the JSON and use it in the body of the API available [here](/docs/openid4vc-api/config-create-digital-wallet-open-id-verification-request-v-3).

After receiving the response, toggle the button provided to dynamically generate a QR code. The EUDI Wallet/Holder can then accept the verification request using the Data Wallet (or any other EU Digital Identity Wallet) by either scanning the QR code or directly accessing the verification request on their mobile device, such as via a browser.

<DcqlStepTemplate
  endpointPath="/v3/config/digital-wallet/openid/sdjwt/verification/send"
  method="POST"
  initialJsonData={{
    presentationDefinitionId: "<presentationDefinitionId>",
    requestByReference: true,
  }}
  extractQrValue={(result) => result?.verificationHistory?.vpTokenQrCode || ""}
/>

## Step 6: Send and Receive Verifiable Presentation (Holder)

The holder wallet accepts (consents) to send the requested credentials.

- **Receive Verification:**
  - Use the `vpTokenQrCode`(step 5) with the API available [here](/docs/openid4vc-api/config-receive-digital-wallet-open-id-verification-v-3/) to receive the verification.
  - Copy the `presentationId` from the JSON response received from **Receive Verification** for use in Step 6b.
- **Filter Verification:**
  - Use that `presentationId` with the API available [here](/docs/openid4vc-api/config-filter-digital-wallet-open-id-verification) to find matching credentials.
  - Save the `<id>` and `<credentialId>` from the response.
- **Send Verification:**
  - Use the `presentationId`, `<id>` and `<credentialId>` with the API available [here](/docs/openid4vc-api/config-send-digital-wallet-open-id-verification-presentation-v-3) to send the credentials to the verifier.

## Step 7: Send and Receive Verifiable Presentation (Verifier/Relying Party)

- The Verfier (Relying Party) receives the requested credentials and can verify it. They may read the received credential by executing the [Read Verification History API](/docs/openid4vc-api/config-read-digital-wallet-open-id-verification-history-v-3).
- From the response received, the `vpTokenResponse` can be decoded using [JWT Decoder](/docs/devtools-jwt-decoder/).
- From the decoded response, the `verifiableCredential` inside the 'vp' can be further decoded to view the received credentials.
