-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from nqminds/vc_rest_api
VC Schemas and VC Rest API
- Loading branch information
Showing
16 changed files
with
543 additions
and
114 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# NIST VC (Verifiable Credential) REST Server | ||
|
||
Provides a REST API server with route to sign data matching schemas in @nqminds/nist-brski-schemas and return a VC and a route to verify a VC and return the data contained within it. No authentication has been added to the Rest API as it is intended to be used only locally and not exposed to external traffic. | ||
|
||
After the @nqminds/nist-brski-schemas schemas have been instantiated on a volt running on the registrar a Rest API Instance can be started on the registrar which may be used to verify VCs received by the registrar. | ||
|
||
A user / process that wishes to communicate information to the registrar must sign into the volt running on the registrar and export their config for the volt. They can then run an instance on the Rest API on their local machine and sign the data they wish to communicate as a VC which can then be communicated to the registrar. At present, only the config of the user who is the owner of the schemas may be used with the Rest API to sign and verify VCs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
#!/usr/bin/env node | ||
|
||
import http from 'node:http'; | ||
import { promisify } from 'node:util'; | ||
import express from "express"; | ||
import server from "../src/server.js"; | ||
|
||
const PORT = process.env.PORT ?? 3000; | ||
|
||
async function main() { | ||
const app = express(); | ||
|
||
/** Setup CORS so that other websites can access this server */ | ||
app.use((req, res, next) => { | ||
// set the CORS policy | ||
res.header('Access-Control-Allow-Origin', '*'); | ||
// set the CORS headers | ||
res.header('Access-Control-Allow-Headers', 'origin, X-Requested-With,Content-Type,Accept, Authorization'); | ||
// set the CORS method headers | ||
if (req.method === 'OPTIONS') { | ||
res.header('Access-Control-Allow-Methods', 'GET, PATCH, DELETE, POST'); | ||
return res.status(200).json({}); | ||
} | ||
next(); | ||
}); | ||
|
||
console.warn( | ||
"CORS: Allowing API connections from any origin.\n" + | ||
"This is a potential security risk." | ||
); | ||
|
||
const router = await server(); | ||
app.use(router); | ||
|
||
const httpServer = http.createServer(app); | ||
|
||
await promisify(httpServer.listen).bind(httpServer)(PORT); | ||
|
||
console.log(`The server is running on port ${PORT}`) | ||
} | ||
|
||
main().catch((error) => { | ||
console.error("Starting the server failed with: ", error); | ||
process.exitCode = 1; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"voltConfigPath": "../volt-config.json" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
{ | ||
"name": "@nqminds/nist_vc_rest_server", | ||
"version": "1.0.0", | ||
"description": "", | ||
"main": "src/server.js", | ||
"bin": "./bin/vc-server.js", | ||
"scripts": { | ||
"dev": "nodemon ./bin/vc-server.js", | ||
"build": "rm -rf build/ && prettier --write src/ && tsc" | ||
}, | ||
"nodemonConfig": { | ||
"ext": "js", | ||
"ignore": [], | ||
"delay": "2" | ||
}, | ||
"author": "", | ||
"type": "module", | ||
"license": "ISC", | ||
"dependencies": { | ||
"@grpc/grpc-js": "^1.9.13", | ||
"@nqminds/verifiable-schemas-toolchain": "^1.0.3", | ||
"@tdxvolt/volt-client-grpc": "^0.15.1", | ||
"express": "^4.18.2", | ||
"express-openapi-validator": "^5.1.2", | ||
"nodemon": "^3.0.2", | ||
"uuid": "^9.0.1" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
import { readFile } from "node:fs/promises"; | ||
import { fileURLToPath } from "node:url"; | ||
import {createRequire} from "node:module"; | ||
import express from 'express'; | ||
import grpc from "@grpc/grpc-js"; | ||
import * as OpenApiValidator from 'express-openapi-validator'; | ||
import {v4 as uuidv4} from "uuid"; | ||
|
||
import { VoltClient } from "@tdxvolt/volt-client-grpc"; | ||
import {sign, verify} from "@nqminds/verifiable-schemas-toolchain/src/verifiable-credentials.js" | ||
|
||
/** | ||
* Automatically calls `next(error)` when an `async function` errors. | ||
* | ||
* @example | ||
* router.get("/my-url/path", asyncHandler(async (req, res) => { | ||
* // automatically calls next(error) on error | ||
* await blah(); | ||
* res.send("done"); | ||
* })); | ||
* | ||
* @template [P=import("express-serve-static-core").ParamsDictionary] | ||
* @template [ResBody=any] | ||
* @template [ReqBody=any] | ||
* @template [ReqQuery=import("express-serve-static-core").Query] | ||
* @template {Record<string, any>} [LocalsObj=Record<string, any>] | ||
* | ||
* @param {( | ||
* (req: import("express-serve-static-core").Request<P, ResBody, ReqBody, ReqQuery, LocalsObj> & { | ||
* user?: import("@nqminds/taibom-client").User}, | ||
* res: import("express-serve-static-core").Response<ResBody, LocalsObj> | ||
* ) => Promise<void> | ||
* )} asyncHandler - The async handler like `asyc (req, res) => {...}`. | ||
* There may be a `req.user` object, if the API route is an authenticated API | ||
* route. | ||
* @returns {import('express').RequestHandler<P, ResBody, ReqBody, ReqQuery, LocalsObj>} | ||
* A callback version of the handler. | ||
*/ | ||
function asyncHandler(asyncHandler) { | ||
return function (req, res, next) { | ||
Promise.resolve(asyncHandler(req, res)).catch((error) => next(error)); | ||
} | ||
} | ||
|
||
/** | ||
* @typedef {object} ServerConfig - Config for NIST VC REST server. | ||
* @property {string} [databaseId] - **Warning**⚠️: This field will be | ||
* overwritten with the ID of the TDX Volt database to use. | ||
* @property {string} serverParentId - ID or Alias of TDX VOLT's parent directory | ||
*/ | ||
|
||
/** | ||
* Creates an instance of the server API routes. | ||
* | ||
* @param {ServerConfig} [config] The configuration object. If not set, | ||
* will default to the `../config.json` file. | ||
* @param {string} [voltConfigPath] - The path to the TDX Volt Configuration file. | ||
* By default, this is the `../volt-config.json` file. | ||
* @returns {Promise<express.Router>} The express router. | ||
*/ | ||
export default async function server(config, voltConfigPath = fileURLToPath( | ||
new URL("../volt-config.json", import.meta.url), | ||
)) { | ||
const router = express.Router(); // eslint-disable-line new-cap | ||
|
||
if (!config) { | ||
config = /** @type {ServerConfig} */ (JSON.parse(await readFile( | ||
new URL("../config.json", import.meta.url), | ||
{encoding: "utf8"}), | ||
)); | ||
} | ||
|
||
if (config.voltConfigPath) { | ||
voltConfigPath = fileURLToPath(new URL(config.voltConfigPath, import.meta.url)) | ||
} | ||
|
||
const client = new VoltClient(grpc); | ||
await client.initialise(voltConfigPath); | ||
await client.connect(); | ||
|
||
// Body parser middleware | ||
router.use(express.urlencoded({ extended: false })); | ||
router.use(express.json()); | ||
|
||
// checks that all requests/responses match OpenAPI spec | ||
const require = createRequire(import.meta.url); | ||
|
||
router.use((err, req, res, next) => { | ||
if (err instanceof OpenApiValidator.error.Unauthorized) { | ||
// print a login box when trying to access an API route directly | ||
// workaround for https://github.com/cdimascio/express-openapi-validator/issues/471 | ||
res.header("WWW-Authenticate", 'Basic realm="User Visible Realm", charset="UTF-8"'); | ||
} | ||
next(err); | ||
}); | ||
|
||
router.get("/hello", asyncHandler(async (req, res) => { | ||
res.send("hello"); | ||
})); | ||
|
||
router.post("/sign/:schemaName", asyncHandler(async (req, res) => { | ||
const schemaName = req.params.schemaName; | ||
const claimBody = req.body; | ||
const schemaId = `https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/${schemaName}.yaml` | ||
const vc = await sign(schemaId, | ||
claimBody, | ||
{client}); | ||
res.send(vc) | ||
})); | ||
|
||
router.post("/verify/:schemaName", asyncHandler(async (req, res) => { | ||
const schemaName = req.params.schemaName; | ||
const vc = req.body; | ||
const manufacturerTrustSchemaId = `https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/${schemaName}.yaml` | ||
const verified = await verify(vc, {client}); | ||
res.send(verified) | ||
})); | ||
|
||
/** Error handling */ | ||
router.use((req, res, next) => { | ||
const error = new Error('not found'); | ||
return res.status(404).json({ | ||
message: error.message | ||
}); | ||
}); | ||
|
||
return router; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
$id: https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/device_manufacturer_binding.yaml | ||
$schema: https://json-schema.org/draft/2019-09/schema | ||
title: Device Manufacturer Binding | ||
description: Binds a manufacturer to a device instance | ||
type: object | ||
properties: | ||
device: | ||
type: string | ||
description: "Id of device being bound" | ||
manufacturer: | ||
type: string | ||
description: "Id of manufacturer device is being bound to" | ||
issuanceDate: | ||
type: string | ||
format: date-time | ||
description: "date-time at which claim was issued" | ||
required: | ||
- device | ||
- manufacturer | ||
- issuanceDate | ||
examples: | ||
- device: 64501d30-fbae-478e-bf72-8b49d47189f0 | ||
manufacturer: e16dfb44-5a6d-41f6-b7a7-c3885a0efc42 | ||
issuanceDate: "2022-02-05T10:30:00.1Z" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
$id: https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/device_trust.yaml | ||
$schema: https://json-schema.org/draft/2019-09/schema | ||
title: Device Trust | ||
description: Statement of trust of a device to connect to the secure network by a user | ||
type: object | ||
properties: | ||
user: | ||
type: string | ||
description: "Id of user stating trust/distrust of device" | ||
device: | ||
type: string | ||
description: "Id of device user is stating trust/distrust of" | ||
trust: | ||
type: boolean | ||
description: "Trust value" | ||
issuanceDate: | ||
type: string | ||
format: date-time | ||
description: "date-time at which claim was issued" | ||
required: | ||
- user | ||
- device | ||
- trust | ||
- issuanceDate | ||
examples: | ||
- user: 3ec4950f-2306-4298-aa01-80190a74eff3 | ||
device: 64501d30-fbae-478e-bf72-8b49d47189f0 | ||
trust: True | ||
issuanceDate: "2022-02-05T10:30:00.1Z" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
$id: https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/device_type_binding.yaml | ||
$schema: https://json-schema.org/draft/2019-09/schema | ||
title: Device Type Binding | ||
description: Binds a device type to a device instance | ||
type: object | ||
properties: | ||
device: | ||
type: string | ||
description: "Id of device being bound" | ||
deviceType: | ||
type: string | ||
description: "Id of device type device instance is being bound to" | ||
issuanceDate: | ||
type: string | ||
format: date-time | ||
description: "date-time at which claim was issued" | ||
required: | ||
- device | ||
- deviceType | ||
- issuanceDate | ||
examples: | ||
- device: 64501d30-fbae-478e-bf72-8b49d47189f0 | ||
deviceType: 76e66647-e791-437e-bf03-f3b030ab1220 | ||
issuanceDate: "2022-02-05T10:30:00.1Z" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
$id: https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/device_type_vulnerable.yaml | ||
$schema: https://json-schema.org/draft/2019-09/schema | ||
title: Device Type Vulnerable | ||
description: States whether a device type is considered vulnerable, whether it is above the allowed vulnerabilities threshold | ||
type: object | ||
properties: | ||
deviceType: | ||
type: string | ||
description: "Id of device type being bound" | ||
vulnerable: | ||
type: boolean | ||
description: "Is device type vulnerable - i.e. it is above allowed vulnerabilities threshold" | ||
issuanceDate: | ||
type: string | ||
format: date-time | ||
description: "date-time at which claim was issued" | ||
required: | ||
- deviceType | ||
- vulnerable | ||
- issuanceDate | ||
examples: | ||
- deviceType: 76e66647-e791-437e-bf03-f3b030ab1220 | ||
vulnerable: False | ||
issuanceDate: "2022-02-05T10:30:00.1Z" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
$id: https://github.com/nqminds/nist-brski/blob/main/packages/schemas/src/manufacturer_trust.yaml | ||
$schema: https://json-schema.org/draft/2019-09/schema | ||
title: Manufacturer Trust | ||
description: Statement of trust of a manufacturer by a user - that the manufacturer's MASA should be trusted to be contacted by the registrar | ||
type: object | ||
properties: | ||
user: | ||
type: string | ||
description: "Id of user stating trust/distrust of manufacturer" | ||
manufacturer: | ||
type: string | ||
description: "Id of manufacturer user is stating trust/distrust of" | ||
trust: | ||
type: boolean | ||
description: "Trust value" | ||
issuanceDate: | ||
type: string | ||
format: date-time | ||
description: "date-time at which claim was issued" | ||
required: | ||
- user | ||
- manufacturer | ||
- trust | ||
- issuanceDate | ||
examples: | ||
- user: 3ec4950f-2306-4298-aa01-80190a74eff3 | ||
manufacturer: e16dfb44-5a6d-41f6-b7a7-c3885a0efc42 | ||
trust: True | ||
issuanceDate: "2022-02-05T10:30:00.1Z" |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.