# Basics

# Subject registration

The first thing you need to do is create some public/private key material for your subjects. We use the term subjects for everything related to vendors, tenants, organizations and clients. Behind every subject there can be multiple DIDs ([decentralized identifiers](https://www.w3.org/TR/did-core/)). For most of the interactions with the Nuts node, you'll be using the subject identifier.

#### Create a subject

```http
POST /internal/vdr/v2/subject

{
  "subject": "my_subject_identifier"
}

```

See [API](https://nuts-node.readthedocs.io/en/latest/pages/integrating/api.html?urls.primaryName=Verifiable%20Data%20Registry%20(v2))

The `subject` in the POST body is optional. If not given, the subject identifier will be generated for you and returned in the result:

```json
{
  "subject": "my_subject_identifier",
  "documents": [
    {
      "id": "did:nuts:B8PUHs2AUHbFF1xLLK4eZjgErEcMXHxs68FteY7NDtCY",
      ...
    },
    {
      "id": "did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142",
      ...
    }
  ]
}

```

You can now use these DIDs to issue and receive Verifiable Credentials.

#### List DIDs

For some operations you still need DIDs. Issuing credentials is an example. You can find your subject's DIDs by calling the following API:

```http
GET /internal/vdr/v2/subject/my_subject_identifier

```

Result:

```
[
  "did:nuts:B8PUHs2AUHbFF1xLLK4eZjgErEcMXHxs68FteY7NDtCY",
  "did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142"
]

```

# Obtaining credentials

After you created a subject with some DID documents, it's time to give meaning to these identifiers. Without Verifiable Credentials, DIDs are just useless identifiers. They receive meaning when another party issues credentials to one of those DIDs. Attestations in the credentials will later be used for authentication &amp; authorization.

#### Issue a Verifiable Credential

With the Nuts node, you can issue any kind of credential from one of your subjects to any resolvable DID (did:nuts, did:web, did:key and did:jwk). What the meaning of the credential is and how it can be used is determined by the use case.

```http
POST /internal/vcr/v2/issuer/vc

{
  "@context": "https://nuts.nl/credentials/v1",
  "type": "NutsOrganizationCredential",
  "issuer": "did:web:example.com:iam:issuer",
  "credentialSubject": {
    "id": "did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142",
    "organization": {
        "name": "Care bears",
        "city": "Care town"
    }
  },
  "withStatusList2021Revocation": true
}

```

See [API](https://nuts-node.readthedocs.io/en/latest/pages/integrating/api.html?urls.primaryName=Verifiable%20Credential%20Registry%20(v2))

The `withStatusList2021Revocation` option allows for credential revocation.

Response:

```http
{
  "@context":[
    "https://nuts.nl/credentials/v1",
    "https://w3id.org/vc/status-list/2021/v1",
    "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json",
    "https://www.w3.org/2018/credentials/v1"
  ],
  "type":["NutsOrganizationCredential","VerifiableCredential"],
  "id":"did:web:example.com:iam:issuer#f2fb02d3-6216-47b9-8e54-b30438a1090e",
  "issuanceDate":"2024-09-09T14:09:50.901123+02:00",
  "issuer":"did:web:example.com:iam"issuer",
  "credentialStatus":{
    "id":"https://example.com/statuslist/did:web:example.com:iam:issuer/1#5",
    "statusListCredential":"https://example.com/statuslist/did:web:example.com:iam:issuer/1",
    "statusListIndex":"5",
    "statusPurpose":"revocation",
    "type":"StatusList2021Entry"
  },
  "credentialSubject":{
    "id":"did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142",
    "organization":{
      "name":"Care bears",
      "city":"Care town"
    }
  },
  "proof":{...}
}

```

#### Load a Verifiable Credential

The Nuts node currently doesn't support a new (Nuts network is deprecated) method for exchanging Verifiable Credentials from issuer to holder. The issuer will have to send the credential to the holder out-of-band. The holder can then upload the credential:

```http
POST /internal/vcr/v2/holder/did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142/vc

{
  "@context":[
    "https://nuts.nl/credentials/v1",
    "https://w3id.org/vc/status-list/2021/v1",
    "https://w3c-ccg.github.io/lds-jws2020/contexts/lds-jws2020-v1.json",
    "https://www.w3.org/2018/credentials/v1"
  ],
  "type":["NutsOrganizationCredential","VerifiableCredential"],
  "id":"did:web:example.com:iam:issuer#f2fb02d3-6216-47b9-8e54-b30438a1090e",
  "issuanceDate":"2024-09-09T14:09:50.901123+02:00",
  "issuer":"did:web:example.com:iam"issuer",
  "credentialStatus":{
    "id":"https://example.com/statuslist/did:web:example.com:iam:issuer/1#5",
    "statusListCredential":"https://example.com/statuslist/did:web:example.com:iam:issuer/1",
    "statusListIndex":"5",
    "statusPurpose":"revocation",
    "type":"StatusList2021Entry"
  },
  "credentialSubject":{
    "id":"did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142",
    "organization":{
      "name":"Care bears",
      "city":"Care town"
    }
  },
  "proof":{...}
}

```

# Service activation

Before another party can interact with you, they will first need to find your endpoints. The discovery service in the Nuts node can help you. The Nuts node can act as both server and client. From a use case definition you'll receive the following information/files:

- **Discovery Service Definition**. A file that contains the ID, server address, allowed DID methods and Presentation Definition for the discovery service. The Presentation Definition lists a number of constraints. The constraint identifiers can be used as additional search parameters.
- **Use case specific endpoints**. Endpoint types like: FHIR, notification, etc. These have to be added through the additional registration parameters.

Example:

```json
{
   "id": "coffeecorner",
   "did_methods": ["web", "nuts"],
   "endpoint": "https://example.com/discovery/coffeecorner",
   "presentation_max_validity": 36000,
   "presentation_definition": {
     "id": "coffeecorner2024",
     "format": {
       "ldp_vc": {
         "proof_type": [
           "JsonWebSignature2020"
         ]
       },
       "jwt_vp": {
         "alg": ["ES256"]
       }
     },
     "input_descriptors": [
       {
         "id": "NutsOrganizationCredential",
         "constraints": {
           "fields": [
             {
               "path": [
                 "$.type"
               ],
               "filter": {
                 "type": "string",
                 "const": "NutsOrganizationCredential"
               }
             },
             {
               "id": "organization_name",
               "path": [
                 "$.credentialSubject.organization.name"
               ],
               "filter": {
                 "type": "string"
               }
             },
             {
               "path": [
                 "$.credentialSubject.organization.city"
               ],
               "filter": {
                 "type": "string"
               }
             }
           ]
         }
       }
     ]
   }
 }

```

The constraint for organization name (`organization_name`) can be used as search parameter.

#### Activate service for subject

```http
POST /internal/discovery/v1/coffeecorner/my_subject_identifier

{
  "registrationParameters": {
    "fhir": "https://api.example.com/fhir",
    "contact": "alice@example.com"
  }
}

```

As you can see, contact information can also be added. Follow the use case requirements.

The response can be a `200 OK` which means the service has been activated immediately. It can also be a `202 Accepted` which means that the Nuts node received your request but was unable to send the activation to the discovery server. The Nuts node will retry periodically. Others can't find you yet. The logs will keep you posted.

To know if you're findable for others, you can perform a search on the registered subject.

# Service search

You can find participants of a use case via their registered services. A use case defines the service identifier and which credentials are required through the presentation definition. Any constraint in the presentation definition with an identifier can also be used in the search query.

```http
GET /internal/discovery/v1/coffeecorner?organization_name=Care* 

```

Matching is case-insensitive and an `*` can be used as wildcard. (Similar to the SQL `LIKE %`)

Some valid examples for query parameters:

- `credentialSubject.givenName=John`
- `credentialSubject.organization.city=Town`
- `credentialSubject.organization.name=Hospital*`
- `credentialSubject.organization.name=*clinic`
- `issuer=did:web:example.com`

See [API](https://nuts-node.readthedocs.io/en/latest/pages/integrating/api.html?urls.primaryName=Discovery%20Service)

Result:

```json
[
  {
    "id":"did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142#049fb56e-1ba8-4e9e-a7af-0071342a1378",
    "credential_subject_id":"did:web:example.com:iam:657f064a-ebef-4f0f-aa87-88ed32db3142",
    "vp":...
    "fields": {
      "organization_name":"Care Bears"
    },
    "registrationParameters": {
      "authServerURL":"https://example.com/oauth2/other_subject_identifier",
      "fhir": "https://api.example.com/fhir",
      "contact": "alice@example.com"
    }
  }
]

```

As you can see in the search results:

- `organization_name` has been added because of the constraint mapping from the presentation definition.
- `registrationParameters` from the service activation are included.
- `authServerURL` has been added autmatically. You need this for the access token request.

# Access tokens

After finding a service endpoint to interact with, it's time to request an access token. You can request one via your own Nuts node:

```http
POST /internal/auth/v2/my_subject_identifier/request-service-access-token

{
  "authorization_server": "https://example.com/oauth2/other_subject_identifier",
  "scope": "coffee",
  "token_type": "Bearer",
  "credentials": [...]
}


```

- The `authorization_server` parameter is taken from the `authServerURL` registration parameter from the search result.
- The scope is determined by the use case.
- The `token_type` by default is `DPoP`, you can also choose for `Bearer`.
- You can pass additional holder credentials via `credentials`. This is a way to embed user identity tokens.

The `scope` is mapped by a policy file to a presentation definition. Policy files are provided by the use case. If your wallet contains the correct credentials according to the presentation definition, an access token will be given:

```json
{
  "access_token": "ciOiJSUzI1NiIsInR5cCI6Ikp",
  "token_type": "Bearer",
  "expires_in": 3600,
}

```

The `access_token` can then be put in the HTTP Authorization header.

# Authentication & authorization

When a request comes in at your resource endpoint, an access token should be available in the HTTP Authorization header. You can validate the token by calling:

```http
POST /internal/auth/v2/accesstoken/introspect

token=ciOiJSUzI1NiIsInR5cCI6Ikp

```

Note: the content-type of this call is `application/x-www-form-urlencoded`.

And the result:

```json
{
  "active":true,  
  "iss": "https://example.com/oauth2/other_subject_identifier",
  "client_id": "https://example.com/oauth2/my_subject_identifier",
  "scope": "coffee",
  "organization_name":"Care Bears"
}

```

Like with the discovery service, any constraint in the presentation definition of the policy file is also added as key/value pair to the introspection result. This is the mechanism to use attestations from presented credentials for authorization purposes.

The token introspection result is the last thing the Nuts node can do for you. From this point you have to apply the authorization policy...