canonical / serial-vault

18 stars 26 forks source link

[![Build Status][travis-image]][travis-url]

Serial Vault

A Go web service that digitally signs device assertion details.

The application can be run in three modes: signing service, admin service and system-user assertion services. All the web services operate under unencrypted HTTP connections, so these should not be exposed to a public network as-is. The services should be protected by web server front-end services, such as Apache, that provide secure HTTPS connections. Also, the admin service does not include authentication nor authorisation, so this service will typically be made available on a restricted network with some authentication front-end on the web server e.g. SSO. Typically, the services will only be available on a restricted network at a factory, though, with additional security measures, the signing service could be made available on a public network.

Some deployment recommendations are provided

The service mode (signing or admin) is defined in the settings.yaml file. The selected service should be accessible on port :8080 or :8081:

The Admin service's CSRF protection sends a cookie over a secure channel. If the cookie is to be sent over an insecure channel, it is needed to workaround it by setting the environment variable:

$ export CSRF_SECURE=disable

When modified that environment variable is set, consider that the current web session must be invalidated in order to changes take effect. That could require a browser restart. NEVER set this configuration in production environments.

Install from Source

If you have a Go development environment set up, we recommend at least Go v1.13 or higher. This project is built and tested on Ubuntu 16.04.7 LTS (Xenial Xerus) with go 1.13. If you wish to build or run the service from source we recommend using LXD container for this purpose. To get started with LXD, please follow this wiki (jump to the LXD section):

  lxc launch ubuntu:16.04 serial-vault -p default -p $USER
  lxc ls
  ssh -A <container-ip>
  serial-vault:~$ git clone https://github.com/canonical/serial-vault.git
  serial-vault:~$ cd serial-vault
  serial-vault:~/serial-vault$ sudo ./setup-container
  serial-vault:~/serial-vault$ make bootstrap
  serial-vault:~/serial-vault$ make install

After this you will find all binaries in the bin/ folder of the project.

@serial-vault:~/serial-vault$ tree bin/
bin/
├── factory
├── serial-vault
├── serial-vault-admin

To run Serial Vault in admin/UI mode you will need a static/ folder. Make sure to setup correct path to this folder in the configuration file with docRoot variable.

Configuration

Sample Serial Vault Configuration:

title: "Serial Vault"
logo: "/static/images/logo-ubuntu-white.svg"

# Path to the assets (${docRoot}/static)
docRoot: "."

# Backend database details
driver: "postgres"
datasource: "postgres://vault:vault@localhost:5432/vault?sslmode=disable"

keystore: "database"
keystoreSecret: "KEYSTORE_SECRET"

# Valid API keys
apiKeys:
  - API_KEY

# 32 bytes long key to protect server from cross site request forgery attacks
csrfAuthKey: "32_BYTES_LONG_CSRF_AUTH_KEY"

Run the service

  $ cd $GOPATH/src/github.com/canonical/serial-vault
  # run the service in sign/API mode
  $ make run-sign
  # run the serivce in admin/UI
  $ make run-admin

Deploy it with Juju

Juju greatly simplifies the deployment of the Serial Vault. A charm bundle is available at the charm store, which deploys everything apart from the Apache front-end units. There is an example of using Juju in the Deployment Guidelines.

Try with docker

  $ git clone https://github.com/canonical/serial-vault
  $ make run-docker
  # remove containers after try
  $ make stop-docker

Development Environment

Contributing

The general workflow is forking the Serial Vault GitHub repository, make changes in a branch and then create a pull request.

Adding new golang dependency

Serial Vault uses go mod to manage its dependencies.

To remove a dependency

Install Go

Follow the instructions to install Go. The current version of the service runs with Go 1.13.

Install the React development environment

Pre-requisites

Install the latest stable version

nvm install lts/*

Select the version to use

nvm ls nvm use lts/*


- Install the nodejs dependencies
```bash
cd serial-vault
npm install

Working with React

The frontend code can be found in webapp-admin directory.

Building static assets locally

# Select the version to use
cd webapp-admin/
nvm ls
nvm use lts/*
npm run build

Production static assets build process

Production build for the frontend part (javascript and css) is semi-automated and done with GitHub Actions. You can find the configuration for this process in .github/workflows/nodejs.yml. The build process starts automatically after the PR is approved and pushed to master.

You can see the build process in actions tab of this project. After the successful build the automation bot will create a PR with the generated build artifact (minified javascript code) in the static/ directory of this project. These PRs can be merged manually.

Run the tests

npm test

API Methods

/v1/version (GET)

Return the version of the serial vault service.

Output message

{
  "version":"2.1-0",
}

/v1/request-id (POST)

Returns a nonce that is needed for the 'serial' request.

Output message

{
  "request-id": "abc123456",
  "success": true,
  "message": ""
}

The request-id is a nonce that can only be used once and must be used before it expires (typically 600 seconds).

/v1/serial (POST)

Generate a serial assertion signed by the brand key.

Takes the details from the device as a serial-request assertion and generates a signed serial assertion.

Input message

The message must be the serial-request assertion format and is best generated using the snapd libraries.

type: serial-request
brand-id: System
model: Router 3400
device-key:
    WkUDQbqFCKZBPvKbwR...
request-id: abc123456
body-length: 10
sign-key-sha3-384: UytTqTvREVhx...

HW-DETAILS
serial: A1228ML

AcLBUgQAAQoABgUCV7R2C...

The HW-DETAILS are optional hardware details in YAML format, but must include the 'serial' tag as that is a mandatory part of the serial assertion.

Output message

The method returns a signed serial assertion using the key from the vault.

/v1/pivot (POST)

Find the model pivot details for a device.

Takes the serial assertion from a device and returns the model pivot details for the device.

Input message

The serial assertion of the manufacturer's device.

Output message

The method returns details of the model pivot, to convert the device to a reseller model.

/v1/pivotmodel (POST)

Generate the model assertion for the pivoted model for a device.

Takes the serial assertion from a device and returns the model assertion for the pivoted model of the device.

Input message

The serial assertion of the manufacturer's device.

Output message

The method returns details of the model assertion of the pivoted model, to convert the device to a reseller model.

/v1/pivotserial (POST)

Generate the serial assertion for the pivoted model for a device.

Takes the serial assertion from a device and returns the serial assertion for the pivoted model of the device.

Input message

The serial assertion of the manufacturer's device.

Output message

The method returns details of the serial assertion of the pivoted model, to convert the device to a reseller model.