Skip to content
Open
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
2 changes: 1 addition & 1 deletion heka-auth-service/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ COPY . .
RUN yarn test
RUN yarn build

FROM node:18-bullseye-slim
FROM node:18-bookworm-slim

RUN apt-get update && apt-get install curl -y

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ export const RequestFieldsVerification = ({
const supportSelectiveDisclosure = useMemo(
() =>
protocolType === ProtocolType.Aries ||
credentialType === Openid4CredentialFormat.SdJwt,
credentialType === Openid4CredentialFormat.SdJwt ||
credentialType === Openid4CredentialFormat.MsoMdoc,
[protocolType, credentialType],
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,5 +42,9 @@ export const credentialTypes: Record<string, Array<Option>> = {
value: Openid4CredentialFormat.LdpVc,
content: Openid4CredentialFormat.LdpVc,
},
{
value: Openid4CredentialFormat.MsoMdoc,
content: Openid4CredentialFormat.MsoMdoc,
},
],
};
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ const offerOpenId4VcCredential = async (
schemaRegistration.credentials as OpenIdVciSchemaRegistration
)?.supportedCredentialId,
context: params.schema.context,
namespace: params.schema.name,
} as BuildCredentialParams);
const body = buildOpenIdCredentialOffer({
id: userId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,15 @@ export interface LdpVcCredential extends OpenIdCredentialCommon {
credentialSubject: Record<string, unknown>;
}

export interface MsoMdocCredential {
credentialSupportedId: string;
format: Openid4CredentialFormat;
namespaces: Record<string, Record<string, unknown>>;
}

export type OpenIdCredential =
| SdJwtCredential
| JwtJsonCredential
| JwtJsonLdCredential
| LdpVcCredential;
| LdpVcCredential
| MsoMdocCredential;
Original file line number Diff line number Diff line change
Expand Up @@ -98,15 +98,32 @@ export const buildLdpVcCredential = ({
credentialSubject: credentialValues,
});

export interface BuildMsoMdocCredentialParams {
credentialSupportedId: string;
credentialValues: Record<string, unknown>;
namespace?: string;
}

export const buildMsoMdocCredential = ({
credentialSupportedId,
credentialValues,
namespace = 'org.iso.18013.5.1',
}: BuildMsoMdocCredentialParams) => ({
credentialSupportedId,
format: Openid4CredentialFormat.MsoMdoc,
namespaces: { [namespace]: credentialValues },
});

export interface BuildCredentialParams {
format: Openid4CredentialFormat;
did: string;
credentialSupportedId: string;
credentialValues: Record<string, string>;
context?: Array<string>;
namespace?: string;
}

export const buildCredential = (params: BuildCredentialParams) => {
export const buildCredential = (params: BuildCredentialParams): OpenIdCredential => {
switch (params.format) {
case Openid4CredentialFormat.SdJwt:
return buildSdJwtCredential(params);
Expand All @@ -116,5 +133,7 @@ export const buildCredential = (params: BuildCredentialParams) => {
return buildJwtJsonLdCredential(params);
case Openid4CredentialFormat.LdpVc:
return buildLdpVcCredential(params);
case Openid4CredentialFormat.MsoMdoc:
return buildMsoMdocCredential(params);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ const requestOpenId4VcPresentation = async (
params.requestedAttributes ??
params.schema.fields?.map((schema) => schema.name) ??
[],
doctype: params.schema.name,
namespace: params.schema.name,
});
const response = await api.post<RequestOpenIdPresentationResponse>(
agencyEndpoints.requestOpenIdPresentation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ export interface BuildOpenIdPresentationRequestParams {
name: string;
attributes: Array<string>;
purpose?: string;
/** doctype for mso_mdoc credentials (e.g. 'org.iso.18013.5.1.mDL') */
doctype?: string;
/** namespace for mso_mdoc claim paths (e.g. 'org.iso.18013.5.1') */
namespace?: string;
}

export const buildSdJwtPresentationRequest = ({
Expand Down Expand Up @@ -93,6 +97,53 @@ export const buildJwtJsonPresentationRequest = ({
};
};

const MDL_DOCTYPE = 'org.iso.18013.5.1.mDL'
const MDL_NAMESPACE = 'org.iso.18013.5.1'
const MDL_ALG = ['ES256', 'ES384', 'ES512', 'EdDSA', 'ESB256', 'ESB320', 'ESB384', 'ESB512']

export const buildMsoMdocPresentationRequest = ({
id,
did,
name,
attributes,
purpose,
doctype = MDL_DOCTYPE,
namespace = MDL_NAMESPACE,
}: BuildOpenIdPresentationRequestParams) => {
return {
publicVerifierId: id,
requestSigner: {
method: 'did',
did: did,
},
presentationExchange: {
definition: {
id: v4(),
name,
input_descriptors: [
{
id: doctype,
format: {
mso_mdoc: {
alg: MDL_ALG,
},
},
constraints: {
limit_disclosure: 'required',
fields: attributes.map((attribute) => ({
path: [`$['${namespace}']['${attribute}']`],
intent_to_retain: false,
})),
},
name,
purpose: purpose ?? 'To obtain credential data',
},
],
},
},
};
};

export const buildOpenIdPresentationRequest = (
params: BuildOpenIdPresentationRequestParams,
) => {
Expand All @@ -103,6 +154,8 @@ export const buildOpenIdPresentationRequest = (
case Openid4CredentialFormat.JwtJsonLd:
case Openid4CredentialFormat.LdpVc:
return buildJwtJsonPresentationRequest(params);
case Openid4CredentialFormat.MsoMdoc:
return buildMsoMdocPresentationRequest(params);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export enum Openid4CredentialFormat {
JwtJson = 'jwt_vc_json',
JwtJsonLd = 'jwt_vc_json-ld',
LdpVc = 'ldp_vc',
MsoMdoc = 'mso_mdoc',
}

export type CredentialFormat = AriesCredentialFormat | Openid4CredentialFormat;
Expand All @@ -26,6 +27,7 @@ export enum Openid4CredentialRegistrationFormat {
JwtJson = 'jwt_vc_json',
JwtJsonLd = 'jwt_vc_json-ld',
LdpVc = 'ldp_vc',
MsoMdoc = 'mso_mdoc',
}

export type CredentialRegistrationFormat =
Expand All @@ -46,6 +48,7 @@ export const credentialFormatToCredentialRegistrationFormat = (
[Openid4CredentialFormat.JwtJsonLd]:
Openid4CredentialRegistrationFormat.JwtJsonLd,
[Openid4CredentialFormat.LdpVc]: Openid4CredentialRegistrationFormat.LdpVc,
[Openid4CredentialFormat.MsoMdoc]: Openid4CredentialRegistrationFormat.MsoMdoc,
};
return map[format];
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,19 @@ interface OpenId4VcLdpVcCredentialSchema {
credentialSubject: Record<string, unknown>;
}

interface OpenId4VcMsoMdocCredentialSchema {
format: Openid4CredentialFormat.MsoMdoc;
id: string;
doctype: string;
claims?: Record<string, unknown>;
}

export type OpenId4CredentialSchema =
| OpenId4VcSdJwtCredentialSchema
| OpenId4VcJwtJsonCredentialSchema
| OpenId4VcJwtJsonLdCredentialSchema
| OpenId4VcLdpVcCredentialSchema;
| OpenId4VcLdpVcCredentialSchema
| OpenId4VcMsoMdocCredentialSchema;

export const convertOpenIdSchema = (schema: OpenId4CredentialSchema) => {
switch (schema.format) {
Expand Down Expand Up @@ -68,6 +76,14 @@ export const convertOpenIdSchema = (schema: OpenId4CredentialSchema) => {
context: schema['@context'],
attributes: Object.keys(schema.credentialSubject ?? {}),
};
case Openid4CredentialFormat.MsoMdoc:
return {
protocolType: ProtocolType.Oid4vc,
id: schema.id,
format: schema.format,
doctype: schema.doctype,
attributes: Object.keys(schema.claims ?? {}),
};
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,9 @@ export const RegistrationTargets = [
credentialFormat: Openid4CredentialRegistrationFormat.JwtJsonLd,
network: DidMethods.Key,
},
{
protocol: ProtocolType.Oid4vc,
credentialFormat: Openid4CredentialRegistrationFormat.MsoMdoc,
network: DidMethods.Key,
},
] as RegisterSchemaFormData[];
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,8 @@ export const VerificationFromTemplate = () => {
const supportSelectiveDisclosure = useMemo(
() =>
verificationTemplate?.protocol === ProtocolType.Aries ||
verificationTemplate?.credentialFormat === Openid4CredentialFormat.SdJwt,
verificationTemplate?.credentialFormat === Openid4CredentialFormat.SdJwt ||
verificationTemplate?.credentialFormat === Openid4CredentialFormat.MsoMdoc,
[verificationTemplate],
);

Expand Down
6 changes: 6 additions & 0 deletions heka-identity-service/docs/swagger-spec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ paths:
- jwt_vc_json-ld
- ldp_vc
- vc+sd-jwt
- mso_mdoc
- name: network
required: true
in: query
Expand Down Expand Up @@ -2448,6 +2449,7 @@ components:
- jwt_vc_json-ld
- ldp_vc
- vc+sd-jwt
- mso_mdoc
network:
type: string
description: Network
Expand Down Expand Up @@ -2660,6 +2662,7 @@ components:
- jwt_vc_json-ld
- ldp_vc
- vc+sd-jwt
- mso_mdoc
network:
type: string
description: Network
Expand Down Expand Up @@ -3444,6 +3447,7 @@ components:
- jwt_vc_json
- jwt_vc_json-ld
- ldp_vc
- mso_mdoc
display:
type: array
items:
Expand Down Expand Up @@ -3648,6 +3652,8 @@ components:
type: boolean
presentationExchange:
type: object
dcql:
type: object
required:
- publicVerifierId
- requestSigner
Expand Down
Loading
Loading