diff --git a/README.md b/README.md index 7d0e624d2..3ad2b3a13 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ relies upon the SSI primitives exposed in the [SSI-SDK](https://github.com/TBD54 The vision for the project is laid out in [this document](doc/service/vision.md). -The project follows a proposal-based improvement format called [SIPs, outlined here](sip/README.md). +The project follows a proposal-based improvement format called [SIPs, outlined here](doc/sip/README.md). Please [join Discord](https://discord.com/invite/tbd), or open an [issue](https://github.com/TBD54566975/ssi-service/issues) if you are interested in helping shape the future of the project. @@ -111,7 +111,7 @@ cd build && docker-compose up -d Managed via: [TOML](https://toml.io/en/) [file](config/dev.toml). Configuration documentation and sample config -files [can be found here](config/README.md). +files [can be found here](doc/README.md#configuration). There are sets of configuration values for the server (e.g. which port to listen on), the services (e.g. which database to use), @@ -128,36 +128,60 @@ authentication and authorization for your use case. ### Health and Readiness Checks -Note: port 3000 is used by default, specified in `config.toml`, for the SSI Service process. If you're running +Note: port 3000 is used by default, specified in `config` folder. An example would be [`dev.toml`](config/dev.toml), for the SSI Service process. If you're running via `mage run` or docker compose, the port to access will be `8080`. Run for health check (status: OK, then you are up): ```shell - ~ curl localhost:3000/health -{"status":"OK"} + ~ curl localhost:3000/health | jq +``` +```json +{ + "status": "OK" +} ``` Run to check if all services are up and ready (credential, did, and schema): ```bash -~ curl localhost:8080/readiness +~ curl localhost:8080/readiness | jq +``` +```json { - "status": { - "status": "ready", - "message": "all service ready" + "status": { + "status": "ready", + "message": "all services ready" + }, + "serviceStatuses": { + "credential": { + "status": "ready" + }, + "did": { + "status": "ready" + }, + "issuance": { + "status": "ready" + }, + "keystore": { + "status": "ready" + }, + "manifest": { + "status": "ready" + }, + "operation": { + "status": "ready" + }, + "presentation": { + "status": "ready" + }, + "schema": { + "status": "ready" }, - "serviceStatuses": { - "credential": { - "status": "ready" - }, - "did": { - "status": "ready" - }, - "schema": { - "status": "ready" - } + "webhook": { + "status": "ready" } + } } ``` @@ -167,7 +191,7 @@ Run to check if all services are up and ready (credential, did, and schema): |--------------------------------------------------------------------------------------------|-------------------------------------------------------------------------------| | [Components Readme](https://github.com/TBD54566975/ssi-service/blob/main/doc/README.md) | Documentation for various components of the SSI Service | | [VISION](https://github.com/TBD54566975/ssi-service/blob/main/doc/VISION.md) | Outlines the project vision | -| [SIPs](sip/README.md) | Proposals for improving the SSI Service | +| [SIPs](doc/sip/README.md) | Proposals for improving the SSI Service | | [VERSIONING](https://github.com/TBD54566975/ssi-service/blob/main/doc/VERSIONING.md) | Project versioning strategy | | [CODEOWNERS](https://github.com/TBD54566975/ssi-service/blob/main/CODEOWNERS) | Outlines the project lead(s) | | [CODE_OF_CONDUCT](https://github.com/TBD54566975/ssi-service/blob/main/CODE_OF_CONDUCT.md) | Expected behavior for project contributors, promoting a welcoming environment | diff --git a/config/.env.example b/config/.env.example index bfd7c9915..4dec46e7f 100644 --- a/config/.env.example +++ b/config/.env.example @@ -1,3 +1,3 @@ -CONFIG_PATH=config/dev/config.toml +# CONFIG_PATH=config/config.toml KEYSTORE_PASSWORD=default-keystore-password DB_PASSWORD=default-db-password \ No newline at end of file diff --git a/doc/config/auth.md b/doc/config/auth.md index 9f26aa836..51f8bbf16 100644 --- a/doc/config/auth.md +++ b/doc/config/auth.md @@ -16,5 +16,37 @@ curl -H "Authorization: Bearer $TOKEN" .... # Extending Authentication and Authorization for production environments -The server uses the []Gin framework](https://github.com/gin-gonic/gin), which allows various kinds of middleware. Look in `pkg/middleware/Authentication.go` and `pkg/middleware/Authorization.go` for details on how you can wire up authentication and authorization for your use case. One such option is the https://github.com/zalando/gin-oauth2 framework. +The server uses the [Gin framework](https://github.com/gin-gonic/gin), which allows various kinds of middleware. Look in [`pkg/server/middleware/authn.go`](../../pkg/server/middleware/authn.go) and [`pkg/server/server.go`](../../pkg/server/server.go) for details on how you can wire up authentication and authorization for your use case. One such option is the https://github.com/zalando/gin-oauth2 framework. +## How to add Authentication to the SSI Service +1. Open [`pkg/server/middleware/authn.go`](../../pkg/server/middleware/authn.go) for a reference to where to add the proper code +```go +func setUpEngine(cfg config.ServerConfig, shutdown chan os.Signal) *gin.Engine { + gin.ForceConsoleColor() + middlewares := gin.HandlersChain{ + gin.Recovery(), + gin.Logger(), + middleware.Errors(shutdown), + middleware.AuthMiddleware(), + } +} +``` + +2. Open [`pkg/server/server.go`](../../pkg/server/server.go) and uncomment line 126 +```go +// uncomment the below line to enable middle ware auth, see doc/config/auth.md for details +middleware.AuthMiddleware() +``` + +3. Reference the [Authentication](#authentication) section for how to create an `AUTH_TOKEN` + +4. Update `.env` with the hash produced in step 3 +```conf +AUTH_TOKEN="8e455e42e94a0f3ac17fe27e9c6a8475800d02c123ba9d2dc0cf1063ef52bd90" +``` + +5. Build and run the server. When making API calls, pass the preimage (unhashed data) in the header +```bash +export TOKEN=hunter2 +curl -H "Authorization: Bearer $TOKEN" +``` \ No newline at end of file diff --git a/doc/config/kms.md b/doc/config/kms.md index 13149e952..eba8d5384 100644 --- a/doc/config/kms.md +++ b/doc/config/kms.md @@ -11,7 +11,8 @@ For production deployments, using external KMS is strongly recommended. To use an external KMS: 1. Create a symmetric encryption key in your KMS. You MUST select the algorithm that uses AES-256 block cipher in - Galois/Counter Mode (GCM). At the time of writing, this is the only algorithm supported by AWS and GCP. + Galois/Counter Mode (GCM). At the time of writing, this is the only algorithm supported by AWS and GCP for symmetric encrypt/decrypt. + In GCP, the algorithm will be called "Google symmetric key." It will be preselected and grayed out. 2. Set the `master_key_uri` field of the `[services.keystore]` section using the format described in [tink](https://github.com/google/tink/blob/9bc2667963e20eb42611b7581e570f0dddf65a2b/docs/KEY-MANAGEMENT.md#key-management-systems) (we use the tink library under the hood). diff --git a/doc/config/toml.md b/doc/config/toml.md index eed9229a3..6082939ff 100644 --- a/doc/config/toml.md +++ b/doc/config/toml.md @@ -1,6 +1,6 @@ # TOML Config File -Config is managed using a [TOML](https://toml.io/en/) [file](https://github.com/TBD54566975/ssi-service/blob/main/config/config.toml). There are sets of configuration values for the server +Config is managed using a [TOML](https://toml.io/en/) [file](../../config/dev.toml). There are sets of configuration values for the server (e.g. which port to listen on), the services (e.g. which database to use), and each service. Each service may define specific configuration, such as which DID methods are enabled for the DID service. @@ -13,12 +13,54 @@ How it works: 1. On startup: SSI-Service loads default values into the `SSIServiceConfig` 2. Checks for a TOML config file: - - If exists...load toml file - - If does not exist...it uses a default config defined in the code inline + - If exists, load toml file + - If does not exist, it uses a default config defined in the code inline 3. Loads the `config/.env` file and adds the env variables defined in this file to the final `SSIServiceConfig` -There are a number of configuration files in this directory provided as defaults. -Specifically, `config.toml`is intended to be used when the service is run as a local go process. There is another -file, `compose.toml`, which is intended to be used when the service is run via docker compose. To make this switch, -it's recommended that one renames the file to `config.toml` and then maintains the original `compose.toml` file as -`local.toml` or similar. +There are a number of configuration files in this directory provided as defaults: + +- `dev.toml`: intended to be used when running the service as a local go process +- `test.toml`: intended to be used when testing the service +- `prod.toml`: intended to be used when running the service via docker compose + +By default, the `SSIServiceConfig` imports `dev.toml`. To use a different TOML file: +1. Copy desired TOML. Use `config.toml` for non-prod (dev/test). Use `compose.toml` for prod on your env. +```bash +# Only use if running in local non-prod (dev/test) +cp config/dev.toml config/config.toml +``` +```bash +# Only use if running in prod via docker compose +cp config/prod.toml config/compose.toml +``` + +2. Copy and rename the `.env.example` to `.env` +```bash +cp config/.env.example config/.env +``` + +3. To use the TOML you selected, you can take 1 of 2 actions below +- Open `docker-compose.yml` and update the `environment` section of `ssi` to set `CONFIG_PATH` and `GIN_MODE` +```yml + environment: + # select either config or compose based on the command you ran in step 1 + - CONFIG_PATH=/app/config/.toml + - JAEGER_HTTP_URL=http://jaeger:14268/api/traces + # select either debug (non-prod) or release (prod) based on the command you ran in step 1 + - GIN_MODE= +``` + +- Open `.env`, uncomment the `CONFIG_PATH` var and update it with the path to the locally desired TOML you copied above +```conf +# select either config or compose based on the command you ran in step 1 +CONFIG_PATH=config/.toml +``` + +5. Add any additional env vars to the `.env` file, e.g +```conf +; DB_PASSWORD & AUTH_TOKEN are user generated +; Be sure to generate your own if in prod +; See auth.md for how to do this +DB_PASSWORD="f52fbd32b2b3b86ff88ef6c490628285f482af15ddcb29541f94bcf526a3f6c7" +AUTH_TOKEN="f52fbd32b2b3b86ff88ef6c490628285f482af15ddcb29541f94bcf526a3f6c7" +``` diff --git a/pkg/server/server.go b/pkg/server/server.go index b4d7dd9b0..e5b836865 100644 --- a/pkg/server/server.go +++ b/pkg/server/server.go @@ -122,6 +122,8 @@ func setUpEngine(cfg config.ServerConfig, shutdown chan os.Signal) *gin.Engine { gin.Recovery(), gin.Logger(), middleware.Errors(shutdown), + // uncomment the below line to enable middle ware auth, see doc/config/auth.md for details + // middleware.AuthMiddleware() } if cfg.JagerEnabled { middlewares = append(middlewares, otelgin.Middleware(config.ServiceName))