---
# System prepended metadata

title: Migrating to Veramo 3.0
tags: [release articles]

---

# Migrating to Veramo 3.0

In Veramo 3.0 we've separated some responsibilities of different plugins that deal with key management.
This enables people to create new kinds of key management systems for Veramo in a way that makes it clearer where private data is stored and reduces the risk of leaking.

As you may already be aware, Veramo has a 2 layer approach to plugins. On the first layer there are top-level _agent plugins_ that can register for events and that export methods to be directly callable on the `agent` object. These plugin methods can also call each other in the same execution context.

In many cases these agent plugins provide some common API for interacting with different protocols or standards implementations. This is where the second level plugins come in. These provide specific implementations that plug-into the top-level ones. These implementations aren't expected to be aware of each-other, so they don't directly interact.

Examples of this pattern include `DIDResolver` with implementations for various DID methods, `DIDManager` with `IDIDProvider` implementations, and of course `KeyManager` with implementations of `AbstractKeyManagementSystem` (We sometimes refer to these as KMS).

## What's new about key management?

The `@veramo/kms-local` is an implementation of `AbstractKeyManagementSystem`.
In the previous versions it was responsible for implementing some crypto algorithms, but it would rely on the top-level `@veramo/key-manager` to provide the actual private key material.

In Veramo 3.0 **`@veramo/key-manager` no longer stores any private key material.**
Instead, `@veramo/kms-local` now uses a `PrivateKeyStore` for hosting the key data.
The `@veramo/data-store` package provides an implementation that uses a database for storing these keys encrypted by a `SecretBox`.

This means there will be some changes for the initial setup of these plugins, and also some changes related to how the database connection is made **in case you already have key material that needs to be migrated**.

## Ok, so how does it affect me?

If you're just starting out, simply follow one of the [getting started guides](https://veramo.io/docs/basics/introduction). Easy peasy.

If you're already working with Veramo and wish to upgrade existing agents to 3.0, you'll have to make some changes to your configuration, depending on how you're using the framework.

It boils down to these 3 steps, but keep reading for more details:
1. Update your database connection to use `migrations`
2. Remove the `SecretBox` parameter from `KeyManager`
3. Add a `PrivateKeyStore` parameter to `KeyManagementSystem` with a `SecretBox` that you were using before with `KeyManager` (and keep the same encryption key) 

### Typescript app config changes

If your agents are part of a typescript app, these changes will look like this:

```typescript=
import {
  // ...
  migrations, // 0. import default veramo migrations
  PrivateKeyStore
} from '@veramo/data-store'

// 1. update your connection config to use migrations
dbConnection = createConnection({
    // ...
    synchronize: false, // switch this to false
    migrations,         // add default veramo migrations
    migrationsRun: true,// add this flag
  })

const agent = createAgent<>({
// ...
    plugins: [
      // 2. key manager: remove SecretBox param
      new KeyManager({
        store: new KeyStore(dbConnection),
        kms: {
          // 3. kms-local: add PrivateKeyStore with SecretBox
          local: new KeyManagementSystem(new PrivateKeyStore(dbConnection, new SecretBox(secretKey))),
        },
      }),
      // ...
    ]})
```

### CLI config changes

```yml
# 0. update the version for your config file
version: 3.0
# ...

# 1. update your database connection to use migrations
dbConnection:
  $require: typeorm?t=function#createConnection
  $args:
    - type: sqlite
      database:
        $ref: /constants/databaseFile
      synchronize: false  # switch off synchronize
      migrationsRun: true # turn on migrations
      migrations:         # use veramo default migrations
        $require: '@veramo/data-store?t=object#migrations'
      logging: false
      entities:
        $require: '@veramo/data-store?t=object#Entities'

# then update your keyManager config:
keyManager:
  $require: '@veramo/key-manager#KeyManager'
  $args:
    - store:
        $require: '@veramo/data-store#KeyStore'
        $args:
          - $ref: /dbConnection
          # 2. remove the SecretBox argument from KeyManager
      kms:
        local:
          $require: '@veramo/kms-local#KeyManagementSystem'
          $args:
            - $require: '@veramo/data-store#PrivateKeyStore'
              $args:
                - $ref: /dbConnection
                # 3. add the SecretBox argument from KeyManager to your PrivateKeyStore
                - $require: '@veramo/kms-local#SecretBox'
                  $args:
                    - $ref: /constants/secretKey
```

Easy, right?

The default `migrations` that we bundle with `@veramo/data-store` take care of moving the encrypted keys to the new table.
Make sure to use the same encryption key with `SecretBox` that you were using before to be able to decrypt the keys in their new location.

### I was using my own `AbstractKeyManagementSystem`, what do I do now?

First of all, **congrats!** [Let us know](https://github.com/uport-project/veramo/discussions/categories/show-and-tell) about it.

The most important thing to keep in mind is that `KeyManager` **no longer holds any private key material**. It only knows about which `AbstractKeyManagementSystem` holds the key.

This means that when a method like `sign()` is called on your KMS, you should only care about the `kid` property of the `IKey` param and nothing else.

Also, it is now the responsibility of the KMS implementation to compute `publicKeyHex` and to decorate a key with meta data when it creates or imports it, before returning the descriptor to the calling `KeyManager`

###### tags: `release articles`