From cb4ca5f4cd302bc635b0bdd5edff36055f2ab40d Mon Sep 17 00:00:00 2001 From: Mirko Mollik Date: Tue, 13 Aug 2024 09:39:39 +0200 Subject: [PATCH] update installation instructions (#94) * update installation instructions Signed-off-by: Mirko Mollik * fix: update documentation Signed-off-by: Mirko Mollik --------- Signed-off-by: Mirko Mollik --- .gitignore | 1 + docs/apps/holder/holder-app.md | 35 ++++++++++++++++++ docs/apps/holder/holder-backend.md | 39 ++++++++++++++++++++ docs/apps/holder/holder-browser-extension.md | 22 +++++++++++ docs/apps/index.md | 13 +++---- docs/apps/issuer/issuer-backend.md | 12 +++++- docs/apps/verifier/verifier-backend.md | 6 ++- docs/community/contributing.md | 4 ++ docs/getting-started/development.md | 12 +++++- docs/getting-started/docker.md | 13 ++++++- docs/getting-started/index.md | 0 docs/getting-started/prerequisites.md | 5 --- docs/getting-started/requirements.md | 20 ++++++++++ docs/getting-started/tech-stack.md | 2 + docs/index.md | 3 +- docs/intention.md | 1 + mkdocs.yml | 3 +- package.json | 3 +- requirements.txt | 2 + 19 files changed, 174 insertions(+), 22 deletions(-) delete mode 100644 docs/getting-started/index.md delete mode 100644 docs/getting-started/prerequisites.md create mode 100644 docs/getting-started/requirements.md create mode 100644 requirements.txt diff --git a/.gitignore b/.gitignore index 6f0a17ea..f95b1cce 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ tmp .env site application.zip +.venv/ # dependencies node_modules diff --git a/docs/apps/holder/holder-app.md b/docs/apps/holder/holder-app.md index e69de29b..67c04efd 100644 --- a/docs/apps/holder/holder-app.md +++ b/docs/apps/holder/holder-app.md @@ -0,0 +1,35 @@ +# Holder App + +The holder app is a client that is interacting with the holder backend. THe business logic is implemented in the backend, the client is only responsible for displaying the data and interacting with the user. + +The application is responsive, so it can be used on mobile devices as well as on desktops. + +There are two ways to receive a credential: + +- **Camera**: The user can scan a QR code that contains either a OID4VCI URL or a OID4VP URL. For this action the permission of the camera is required. +- **Clipboard**: When going into the scan view, the application will automatically check the clipboard for a valid URL. This validation is done by checking if the URL starts with `oid4vci://` or `oid4vp://` on the client. For this action the permission of the clipboard is required. In case there was no permission granted to read from the clipboard, the user is able to manually paste the URL into the input field via the menu icon in the top right corner. + +## Tech stack + +Angular is used to build the frontend with the esbuild builder. It is also built as a Progressive Web App (PWA) to allow the user to install the app on the device. + +## Configuration + +In the app initialization, the app is loading the `config.json` file from the asset folder. This approach allows to change the configuration without rebuilding the app. The configuration can be mounted into the docker container. + +The file includes the following properties: + +- backendUrl: the url of the backend service + +In development mode, you need to update the `config.json` file in the `src/assets` folder. In production, you can mount the file into the docker container. +TODO: to avoid a cached config file, a random parameter should be added to the url. + +## Authentication + +The application will send a GET request to `$backendUrl/auth` to get the OIDC configuration. The configuration will be used to authenticate the user via the keycloak instance. + +It is also possible on the login screen to change the backend url to a different instance. This is useful for testing different environments or to use one hosted client instance. In this case the manuel configured backendUrl is stored in the local storage. When the app is started, it will prioritize the stored url over the one in the config file. + +## Language support + +The application is right now only available in English. A multi language support is planned for the future. diff --git a/docs/apps/holder/holder-backend.md b/docs/apps/holder/holder-backend.md index e69de29b..dfd274e4 100644 --- a/docs/apps/holder/holder-backend.md +++ b/docs/apps/holder/holder-backend.md @@ -0,0 +1,39 @@ +# Holder backend + +The holder backend is a service for managing the wallet of multiple users. It will store the credentials and will interact with the different relying parties to receive or present credentials. + +## Tech stack + +The backend is based on nestjs, where all endpoints are published as rest api. The OpenAPI interface can be found at `/api`. + +## Configuration + +Configuration is done via environment variables. By default the service will use the `.env` file in the app folder, but for production you can pass the variables via the environment into the docker container. +The required variables will be checked on startup. If a variable is missing, the service will exit with an error message. + +## Database + +The backend is using `typeorm`, allowing to use different database. Right now it supports `sqlite` and `postgres`. The type is define via the `DB_TYPE` environment variable. The default value is `postgres`. + +## Key management + +There are two different key management systems supported by the backend to manage the keys of the users. + +- `db`: the keys are stored in the database +- `vault`: the keys are stored in a hashicorp vault instance + +The type is set via `KM_TYPE`, the default value is `db`. + +The implementation of other vault systems or other approaches are possible by implementing the `KeysService` interface. + +The key management option is equal for all users and can not be set individually. + +## Authentication + +Authentication is realized via open id connect. The JWT needs to have the role `holder` to be able to access the endpoints. + +To validate if the token got revoked, the backend needs a service account with the required permissions. + +## Health check + +The service is exposing a health check endpoint at `/health`. It will return a `200` status code if the service is healthy. diff --git a/docs/apps/holder/holder-browser-extension.md b/docs/apps/holder/holder-browser-extension.md index e69de29b..7b553fa8 100644 --- a/docs/apps/holder/holder-browser-extension.md +++ b/docs/apps/holder/holder-browser-extension.md @@ -0,0 +1,22 @@ +# Holder Browser Extension + +The browser extension is a client that available as a browser extension. Right now there is only a chrome extension available. Like the holder app, the business logic is implemented in the backend, the client is only responsible for displaying the data and interacting with the user. + +Most of the code is shared between the holder app and the browser extension. The main difference is the way how to interact with QR-Codes. For this the extension is using the `chrome.tabs` API to inject a content script into the current tab. This script is responsible for scanning all images on the page and check if it is a QR-Code. If a QR-Code is found with the correct schema like `oid4vci://` or `oid4vp://`, the extension will render a button next to the QR-Code that the user can click to start the scanning process. + +## Tech stack + +Angular is used to build the frontend with the webpack builder. The older builder is used because it allows to compile multiple entry points. +Esbuild could also be used to speed up the build, but then two jobs have to be executed to compile the app and the background script. + +## Configuration + +In the app initialization, the app is loading the `config.json` file from the asset folder. This approach allows to change the configuration without rebuilding the app. This configuration can be replaced in the compiled extension. But when the extension was pushed to the Chrome Web Store, the configuration is fixed. + +## Authentication + +Chapter is equal to the [holder app](../holder/holder-app.md#authentication). + +## Language support + +Chapter is equal to the [holder app](../holder/holder-app.md#language-support). diff --git a/docs/apps/index.md b/docs/apps/index.md index ceca776a..00eae5d0 100644 --- a/docs/apps/index.md +++ b/docs/apps/index.md @@ -5,26 +5,25 @@ The repository is structured as follows: - `.github` includes specific GitHub actions workflows. - `.vscode` includes specific settings for Visual Studio Code. - `apps` includes all applications. -- `deploys` includes deployment configurations for the different apps. -- `docker` includes Dockerfile for specific dependencies like keycloak. +- `deploys` includes deployment configurations for the different apps and dependencies with docker. - `docs` includes documentation for this repository. -- `patches` includes patches for specific libraries. +- `libs` includes shared code between the apps. +- `patches` includes patches for specific dependencies of node. ## Apps connection + ![Overview](https://www.mermaidchart.com/raw/832e87e0-a10e-40b3-b103-ed79ad860b6e?theme=light&version=v0.1&format=svg) To watch the code dependency between the apps and libs, you can use the following command: + ```bash npx nx graph ``` - -## Apps connection -![Overview](https://www.mermaidchart.com/raw/832e87e0-a10e-40b3-b103-ed79ad860b6e?theme=light&version=v0.1&format=svg) - ## Issuance flow ![Issuance process](https://www.mermaidchart.com/raw/36b70fe7-7b53-448a-8f65-2f29b1c515af?theme=light&version=v0.1&format=svg) ## Presentation flow + ![Presentation flow](https://www.mermaidchart.com/raw/fd2e141e-9a29-43ee-b16f-2bafc701bbb0?theme=light&version=v0.1&format=svg) diff --git a/docs/apps/issuer/issuer-backend.md b/docs/apps/issuer/issuer-backend.md index 0448f023..5879ca1c 100644 --- a/docs/apps/issuer/issuer-backend.md +++ b/docs/apps/issuer/issuer-backend.md @@ -1,19 +1,26 @@ # Issuer backend -The issuer backend is a service for issuing credentials to users. It will also store issued credential so they can be revoked. The different schemas of credentials are mounted into the container are fetched on demand. +The issuer backend is a service for issuing credentials to users. It will also store issued credential so they can be revoked. + +Credential templates can be mounted to the docker container to be added to the internal database. There are also API endpoints to add, update and delete templates. ## Tech stack + The backend is based on nestjs, where all endpoints are published as rest api. The OpenAPI interface can be found at `/api`. ## Configuration -Configuration is done via environment variables. By default the service will use the `.env` file in the root folder, but for production you can pass the variables via the environment into the docker image. + +Configuration is done via environment variables. By default the service will use the `.env` file in the app folder, but for production you can pass the variables via the environment into the docker container. The required variables will be checked on startup. If a variable is missing, the service will exit with an error message. ## Database + The backend is using `typeorm`, allowing to use different database. Right now it supports `sqlite` and `postgres`. The type is define via the `DB_TYPE` environment variable. The default value is `postgres`. ## Key management + Two different key management systems are supported by the backend. + - `file`: the keys are stored unencrypted in the file system - `vault`: the keys are stored in a hashicorp vault instance @@ -26,4 +33,5 @@ The implementation of other vault systems or other approaches are possible by im Authentication is realized via open id connect. The JWT needs to have the role `issuer` to be able to access the endpoints. ## Health check + The service is exposing a health check endpoint at `/health`. It will return a `200` status code if the service is healthy. diff --git a/docs/apps/verifier/verifier-backend.md b/docs/apps/verifier/verifier-backend.md index 68ffc539..84232505 100644 --- a/docs/apps/verifier/verifier-backend.md +++ b/docs/apps/verifier/verifier-backend.md @@ -3,15 +3,18 @@ The verifier backend is a service for verifying credentials of users. The verification templates are stored in the filesystem and will be loaded on demand. ## Tech stack + The backend is based on nestjs, where all endpoints are published as rest api. The OpenAPI interface can be found at `/api`. ## Configuration + Configuration is done via environment variables. By default the service will use the `.env` file in the root folder, but for production you can pass the variables via the environment into the docker image. The required variables will be checked on startup. If a variable is missing, the service will exit with an error message. - ## Key management + Two different key management systems are supported by the backend. + - `file`: the keys are stored unencrypted in the file system - `vault`: the keys are stored in a hashicorp vault instance @@ -24,4 +27,5 @@ The implementation of other vault systems or other approaches are possible by im Authentication is realized via open id connect. The JWT needs to have the role `verifier` to be able to access the endpoints. ## Health check + The service is exposing a health check endpoint at `/health`. It will return a `200` status code if the service is healthy. diff --git a/docs/community/contributing.md b/docs/community/contributing.md index 56688a0a..83a9363f 100644 --- a/docs/community/contributing.md +++ b/docs/community/contributing.md @@ -1 +1,5 @@ +# Contributing + Contributions are always welcome. When opening a pull request, please make sure it is signed and explain the changes you made. In case you want to discuss about a new feature/change, open an issue and we can discuss it there. + +To ask specific questions, you can also join our [Discord](https://discord.gg/ac2AfUaV) server. There you will get regular update about the project and upcoming meetings. diff --git a/docs/getting-started/development.md b/docs/getting-started/development.md index a98f313f..02cfcea8 100644 --- a/docs/getting-started/development.md +++ b/docs/getting-started/development.md @@ -1,5 +1,13 @@ +# Development + To install all dependencies, run `pnpm install` in the root folder. -Each app has its own `package.json` with specific jobs. In the root folder is one `package.json` with global jobs like `build`, `clean` and `lint`. +Each app has its own `project.json` with specific jobs. You can either run them via the command line or via the plugin for your editor. + +The command `pnpm run init` will generate `.env` files for each app based on the example file. + +For vscode are pre defined tasks in the `.vscode` folder. You can run them via the command palette or the shortcut `ctrl+shift+p` and type `Run Task`. The `Start issuer, holder, verifier` task for example will start all three apps with their frontend and backend. The keycloak instance has to be started by yourself since it is not part of the monorepo. You can find it in the `deploys/keycloak` folder and start it with `docker-compose up -d`. + +## Known limitations -The command `pnpm run -r init` will generate `.env` files for each app based on the example file. Applications inside the `apps` folder will not use the `.env` file in the root folder, this is only for the docker-compose setup. Instead use the `.env` files in the apps folder. In case it's an angular application, use the config file in the `assets/config` folder. +When you are running node based tasks and you are adding or removing a dependency, the task will stop the nx daemon will not restart by itself when there are file changes in the app. To fix this, run `pnpm exec nx reset`. After this all node based tasks will work again as expected. diff --git a/docs/getting-started/docker.md b/docs/getting-started/docker.md index 98cd2fb7..b7441e21 100644 --- a/docs/getting-started/docker.md +++ b/docs/getting-started/docker.md @@ -1,14 +1,19 @@ # Running Docker images + To run the docker compose setup, copy the `.env.example` to `.env` in the root folder. The example file comes with an example configuration that should be changed when used in production. Most of the services are validating if the required environment variables are set, if not the process will exit with an error message. ## Building containers + The containers are built via the tasks in each nx app like: + ```bash nx run holder-app:container -``` +``` + To build multiple projects at once, you can use the `run-many` command: + ```bash nx run-many --target=container --all ``` @@ -16,10 +21,13 @@ nx run-many --target=container --all By default the containers are built with the `latest` tag and will not be pushed to the registry. When pushed to the `main` branch of the repo, the github action will push the latest version to the registry. ## Known limitations + When keycloak and the backend are running in docker, the host has to be set `host.docker.internal`. Otherwise the backend is not able to reach the keycloak instance. Make also sure the frontends are using `host.docker.internal` as the keycloak endpoint. Otherwise the token will have the wrong issuer and the backend will reject the token. TODO: the usage of vault should be moved into file. + ## Vault + To secure your keys, you are able to use [vault by hashicorp](https://developer.hashicorp.com/vault), otherwise the keys are either stored in the filesystem for the issuer and verifier or in the unencrypted database for the wallet. Right now it will spin up a vault instance in dev mode and will not persist the keys after a restart. In the `.env` in the root folder, you can set a token you need for authentication. @@ -27,11 +35,13 @@ Right now it will spin up a vault instance in dev mode and will not persist the ### Using in the cloud wallet Configure the environment variables in the `.env` to tell the service to use vault: + ```env KM_TYPE=vault VAULT_URL=http://localhost:8200/v1/transit VAULT_TOKEN=root ``` + The server does not support multiple key management systems in parallel and also no import or export feature. So decide at the beginning which type of key management you want to use. TODO: we also need key management for the accounts to support multiple keys, because right now we use the user-id for the key reference, so each user is only able to store one key. We need a mapping table for the keys and the user-id. @@ -63,4 +73,5 @@ Update the docker container like this: VAULT_ADDR: http://127.0.0.1:8200 entrypoint: vault server -config=/vault/config/config.hcl ``` + Get familiar with the [vault deployment guide](https://developer.hashicorp.com/vault/tutorials/getting-started/getting-started-deploy). This current documentation is not fully covered to run vault in production! diff --git a/docs/getting-started/index.md b/docs/getting-started/index.md deleted file mode 100644 index e69de29b..00000000 diff --git a/docs/getting-started/prerequisites.md b/docs/getting-started/prerequisites.md deleted file mode 100644 index 7150ba2b..00000000 --- a/docs/getting-started/prerequisites.md +++ /dev/null @@ -1,5 +0,0 @@ -- node v20 (https://nodejs.org/en/download/package-manager) -- pnpm v8 (v9 has some issues with the nx workspace) -- editor [plugin for nx](https://nx.dev/getting-started/editor-setup) (optional) - -For an easy development setup, it is recommend to use vscode with the nx plugin to start tasks like building, testing and linting or to generate new code. You can also use Webstorm with the nx plugin, [see here](https://nx.dev/getting-started/editor-setup#official-integrations). diff --git a/docs/getting-started/requirements.md b/docs/getting-started/requirements.md new file mode 100644 index 00000000..edefdf22 --- /dev/null +++ b/docs/getting-started/requirements.md @@ -0,0 +1,20 @@ +# Requirements + +- [node v20](https://nodejs.org/en/download/package-manager) +- [pnpm v9](https://pnpm.io/installation) +- [docker](https://docs.docker.com/get-docker) in case you want to use keycloak and the database in docker +- editor [plugin for nx](https://nx.dev/getting-started/editor-setup) (optional) + +For an easy development setup, it is recommend to use vscode with the nx plugin to start tasks like building, testing and linting or to generate new code. You can also use Webstorm with the nx plugin, [see here](https://nx.dev/getting-started/editor-setup#official-integrations). + + +## Running the documentation + +To run `mkdocs` locally: + +```bash +python3 -m venv .venv +source .venv/bin/activate +pip3 install -r requirements.txt +mkdocs serve +``` diff --git a/docs/getting-started/tech-stack.md b/docs/getting-started/tech-stack.md index e590023b..43f27361 100644 --- a/docs/getting-started/tech-stack.md +++ b/docs/getting-started/tech-stack.md @@ -1,3 +1,5 @@ +# Tech Stack + Typescript as programming language: large community and good support for wallet related libraries. Of course it does not perform as good as Rust, but it's easier to write and maintain for the current state of the project. It is possible to write different parts of the project in Rust or any other language later on. Angular as frontend framework: All frontend applications are written in Angular. There was no intention to build a react native application so far, but it is possible to do so. Since the client is primarily job is to render information and not to execute business actions, other clients like a react native app, vanilla js or even a flutter app can be implemented. diff --git a/docs/index.md b/docs/index.md index 31173341..4b7e1b01 100644 --- a/docs/index.md +++ b/docs/index.md @@ -2,5 +2,6 @@ credhub is comprehensive monorepo including a cloud wallet for natural persons together with a minimal issuer and verifier service. The cloud wallet will host all credentials and key pairs, including the business logic to receive and present credentials. -# License +## License + This project is licensed under the Apache 2.0 License diff --git a/docs/intention.md b/docs/intention.md index ff662920..cfd0ab7d 100644 --- a/docs/intention.md +++ b/docs/intention.md @@ -1,6 +1,7 @@ # Intention ## Why a cloud wallet + A cloud wallet is able to move the whole complexity of the SSI algorithms to the server side, so the clients only need to render the data. This makes the development of new clients or integration into existing applications much easier. It also provides an equal security level for all users and does not exclude any smartphones because of their hardware capabilities. Besides that it allows the user to access his credentials from multiple devices without the need to sync them. Of course the user is losing offline capabilities and has to trust the server to not misuse personal data. But this is a tradeoff that can be acceptable for many use cases when you want to start with verifiable credentials with great user experience and low development effort. diff --git a/mkdocs.yml b/mkdocs.yml index d6882877..3a6d8b5e 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -89,8 +89,7 @@ nav: - Intention of this project: intention.md - Credential Profile: credential-profile.md - Getting Started: - - Getting Started: getting-started/index.md - - Prerequisites: getting-started/prerequisites.md + - Requirements: getting-started/requirements.md - Tech Stack: getting-started/tech-stack.md - Development: getting-started/development.md - Docker: getting-started/docker.md diff --git a/package.json b/package.json index 40e6486a..b25594c7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ } ], "scripts": { - "sentry-cli": "sentry-cli" + "sentry-cli": "sentry-cli", + "init": "pnpm exec nx run-many --target=init --all=true" }, "description": "A monorepo including multiple apps for SSI", "author": "Mirko Mollik ", diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..9a8a4ca4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +mkdocs +mkdocs-material