Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions docs/docs/Infrastructure/eID-Wallet.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,14 +170,16 @@ When a new user first opens the wallet:
```
Wallet → Registry: GET /entropy
Registry → Wallet: JWT entropy token
Wallet → Provisioner: POST /provision (entropy, namespace, publicKey)
Provisioner → Registry: Request key binding certificate
Registry → Provisioner: JWT certificate
Wallet → Provisioner: POST /provision (entropy, namespace, publicKey?)
Provisioner → Registry: Request key binding certificate (if publicKey provided)
Registry → Provisioner: JWT certificate (if publicKey provided)
Provisioner → Wallet: w3id, evaultUri
```

**Note**: The `/provision` endpoint is part of the Provisioner service, not eVault Core. This is the **provisioning protocol** - any vault provider should expose such an endpoint to enable eVault creation.

**Note**: The `publicKey` parameter is optional. User eVaults require it for signature verification and key binding, while keyless eVaults (platforms, groups) can be provisioned without it.

### Platform Authentication

User authenticating their eName to a platform:
Expand Down Expand Up @@ -343,14 +345,14 @@ const provisionResponse = await fetch(`${provisionerUrl}/provision`, {
registryEntropy: entropyToken,
namespace: namespace,
verificationId: verificationCode,
publicKey: publicKey
publicKey: publicKey // Optional: omit for keyless eVaults (platforms, groups)
})
});

const { w3id, uri } = await provisionResponse.json();
```

**Note**: The `/provision` endpoint is hosted by the Provisioner service, not eVault Core.
**Note**: The `/provision` endpoint is hosted by the Provisioner service, not eVault Core. The `publicKey` parameter is optional - it's required for user eVaults that need signature verification, but can be omitted for keyless eVaults like platforms or groups.

### Platform Authentication

Expand Down
33 changes: 27 additions & 6 deletions docs/docs/Infrastructure/eVault-Key-Delegation.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ The default key ID is `"default"` and is used for all signing operations.

### Setting Keys During eVault Creation

During the eVault provisioning process (onboarding), the public key can be set directly when creating the eVault. The `/provision` endpoint accepts a `publicKey` parameter:
During the eVault provisioning process (onboarding), the public key can be set directly when creating the eVault. The `/provision` endpoint accepts an optional `publicKey` parameter:

**Provision Request:**
```http
Expand All @@ -36,17 +36,21 @@ Content-Type: application/json
"registryEntropy": "<entropy-token>",
"namespace": "<w3id>",
"verificationId": "<verification-code>",
"publicKey": "z3059301306072a8648ce3d020106082a8648ce3d03010703420004..."
"publicKey": "z3059301306072a8648ce3d020106082a8648ce3d03010703420004..." // Optional
}
```

When provisioning an eVault during onboarding, the eID wallet:
**Note**: The `publicKey` parameter is optional. It is required for user eVaults that need key binding for signature verification, but can be omitted for keyless eVaults (such as platform or group eVaults) that don't require cryptographic identity.

When provisioning a user eVault during onboarding, the eID wallet:
1. Generates or retrieves the public key using `getApplicationPublicKey()`
2. Includes the `publicKey` in the provision request
3. The eVault stores the public key and generates a key binding certificate automatically

This eliminates the need for a separate sync step when the eVault is first created.

For platform or group eVaults that don't need key binding, the `publicKey` can be omitted entirely.

### Syncing Public Keys to eVault

The public key syncing is an autonomous process done by the eID Wallet when linking new devices to the same eName.
Expand Down Expand Up @@ -155,7 +159,7 @@ X-ENAME: @user.w3id
### Setting Public Key During eVault Creation

```typescript
// During onboarding - provision eVault with public key
// During onboarding - provision user eVault with public key
const publicKey = await getApplicationPublicKey(); // Get public key from KeyService

const provisionResponse = await axios.post(
Expand All @@ -164,11 +168,28 @@ const provisionResponse = await axios.post(
registryEntropy,
namespace: uuidv4(),
verificationId,
publicKey: publicKey, // Public key included in provision request
publicKey: publicKey, // Optional: include for user eVaults, omit for keyless eVaults
}
);

// eVault is created with the public key already stored (if provided)
const { w3id, uri } = provisionResponse.data;
```

For keyless eVaults (platforms, groups), omit the `publicKey` parameter:

```typescript
// Provision a keyless eVault (e.g., for a platform or group)
const provisionResponse = await axios.post(
new URL("/provision", provisionerUrl).toString(),
{
registryEntropy,
namespace: uuidv4(),
verificationId,
// No publicKey - this is a keyless eVault
}
);

// eVault is created with the public key already stored
const { w3id, uri } = provisionResponse.data;
```

Expand Down
5 changes: 3 additions & 2 deletions docs/docs/W3DS Protocol/Signature-Formats.md
Original file line number Diff line number Diff line change
Expand Up @@ -328,8 +328,9 @@ The provisioning process creates an eVault tied to your generated public key:
- `registryEntropy`: JWT token from step 1
- `namespace`: Identifier from step 2
- `verificationId`: Verification code (demo code or your verification ID)
- `publicKey`: Multibase-encoded public key from key generation
- Provisioner validates entropy, generates W3ID, creates eVault, stores public key, and requests key binding certificate from Registry
- `publicKey` (optional): Multibase-encoded public key from key generation
- Provisioner validates entropy, generates W3ID, creates eVault, and if publicKey is provided, stores it and requests key binding certificate from Registry
- **Note**: `publicKey` is required for user eVaults that need signature verification, but optional for keyless eVaults (platforms, groups)

4. **Receive Credentials**
- Receive `w3id` (eName) and `uri` (eVault URI) in response
Expand Down
7 changes: 4 additions & 3 deletions infrastructure/evault-core/src/core/http/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -682,7 +682,6 @@ export async function registerHttpRoutes(
"registryEntropy",
"namespace",
"verificationId",
"publicKey",
],
properties: {
registryEntropy: { type: "string" },
Expand Down Expand Up @@ -808,8 +807,10 @@ export async function registerHttpRoutes(
console.log(
`[MIGRATION] No metaEnvelopes found for eName: ${eName}`,
);
return reply.status(400).send({
error: `No metaEnvelopes found for eName: ${eName}`,
return reply.status(200).send({
success: true,
count: 0,
message: "No metaEnvelopes to copy",
});
}

Expand Down
12 changes: 8 additions & 4 deletions infrastructure/evault-core/src/services/ProvisioningService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface ProvisionRequest {
registryEntropy: string;
namespace: string;
verificationId: string;
publicKey: string;
publicKey?: string;
}

export interface ProvisionResponse {
Expand Down Expand Up @@ -41,17 +41,21 @@ export class ProvisioningService {
if (
!registryEntropy ||
!namespace ||
!verificationId ||
!publicKey
!verificationId
) {
return {
success: false,
error: "Missing required fields",
message:
"Missing required fields: registryEntropy, namespace, verificationId, publicKey",
"Missing required fields: registryEntropy, namespace, verificationId",
};
}

// Log if keyless provisioning
if (!publicKey) {
console.log(`[PROVISIONING] Keyless eVault provisioning (no publicKey provided)`);
}

// Verify the registry entropy token
let payload: any;
try {
Expand Down
Loading