Skip to main content
Version: 0.7

Agent configuration

This page describes what you pass to new Agent(), the modules every agent has, and how to start and stop an agent. The other pages in this section cover the choices you make when you set up an agent.

Choices to make​

ChoiceMobile walletServerDetails
StorageAskar on SQLiteDrizzle on PostgreSQL, or on SQLite for a single instance or developmentStorage
Key managementAskar, plus the secure environment for keys that must stay in hardwareAskar, with its storage turned offKey management
CacheThe defaultThe default for one agent, InMemoryLruCache with tenants, Redis with several instancesCaching
Multi-tenancyNot neededOnly when one service hosts many isolated issuers, verifiers or walletsMulti-tenancy

For tests, use Drizzle on an in-memory SQLite database and keep the keys in memory with the Node.js backend.

Agent options​

OptionDescription
dependenciesRequired. The platform implementations of the file system, fetch, WebSocket and events: agentDependencies from @credo-ts/node or @credo-ts/react-native.
modulesThe modules of the agent, keyed by the name of their API. Include a storage module, Drizzle or Askar: without one, new Agent() throws Missing required dependency: 'StorageService'.
configAgent-wide settings, described below.

Config​

FieldDefaultDescription
loggerConsoleLogger at LogLevel.OffThe logger of the agent and its modules. See Logging.
autoUpdateStorageOnStartupfalseUpdate the storage during initialize() when it was written by an older version of Credo. See Storage updates.
allowInsecureHttpUrlsfalseAccept http:// URLs where HTTPS is otherwise required, such as OpenID4VC endpoints. For local development only. The OpenID4VC module applies it to the whole process, so it also affects other agents in it.
validitySkewSeconds30The clock skew, in seconds, allowed when checking the validity period of credentials, status lists and other signed objects. Phones often run a little behind.
getTrustedIssuersForVerificationnoneA callback that returns the DIDs and X.509 certificates to trust for a verification. See Trusted issuers.

Default modules​

Credo registers these modules on every agent:

KeyModuleAPI
didsDidsModuleagent.dids
kmsKeyManagementModuleagent.kms
sdJwtVcSdJwtVcModuleagent.sdJwtVc
mdocMdocModuleagent.mdoc
w3cCredentialsW3cCredentialsModuleagent.w3cCredentials
w3cV2CredentialsW3cV2CredentialsModuleagent.w3cV2Credentials
w3cDataIntegrityW3cDataIntegrityModuleagent.w3cDataIntegrity
x509X509Moduleagent.x509
tokenStatusListTokenStatusListModuleagent.tokenStatusList
genericRecordsGenericRecordsModuleagent.genericRecords
cacheCacheModule with a SingleContextStorageLruCache of 500 entriesnone
dcqlDcqlModulenone
pexDifPresentationExchangeModulenone

The kms module starts without a backend. AskarModule adds one, also when Drizzle stores the records. Without Askar, configure a backend yourself (see Key management). The default cache doesn't work with multi-tenancy, so replace it when you use tenants (see Caching).

Replace a default module​

To configure a default module, pass your own instance under the same key:

agent.ts
import {
Agent,
ConsoleLogger,
DidsModule,
JwkDidRegistrar,
JwkDidResolver,
KeyDidRegistrar,
KeyDidResolver,
LogLevel,
WebDidResolver,
} from '@credo-ts/core'
import { agentDependencies } from '@credo-ts/node'

function getAgentModules() {
return {
...storage, // Storage and key management, see Agent setup
// Same key as the default module, so it replaces it
dids: new DidsModule({
registrars: [new KeyDidRegistrar(), new JwkDidRegistrar()],
resolvers: [new KeyDidResolver(), new JwkDidResolver(), new WebDidResolver()],
}),
}
}

const agent = new Agent({
config: {
logger: new ConsoleLogger(LogLevel.Warn),
},
dependencies: agentDependencies,
modules: getAgentModules(),
})

The API stays where it was, at agent.dids. When you pass resolvers or registrars to the DidsModule, your list replaces the defaults, except for did:key and did:peer, which are always added.

Module APIs and types​

Default modules are at the top level, for example agent.dids, also when you replace them. Other modules are under agent.modules, for example agent.modules.askar or agent.modules.tenants. The exceptions are didcomm and openid4vc: registered under exactly those keys, they're also at agent.didcomm and agent.openid4vc. Modules without an API, such as cache, have no property on the agent.

The Agent class infers these types from the modules you pass to the constructor. To type an agent you pass to other functions, derive the type from a function that returns the modules:

export type MyAgent = Agent<ReturnType<typeof getAgentModules>>

export async function createDid(agent: MyAgent) {
const { didState } = await agent.dids.create({
method: 'jwk',
options: { createKey: { type: { kty: 'EC', crv: 'P-256' } } },
})
return didState.did
}

Agent without a type argument accepts any agent, but loses the types of agent.modules.

Start and stop the agent​

await agent.initialize()
console.log(`Created ${await createDid(agent)}`)

await agent.shutdown()
console.log(`Agent initialized: ${agent.isInitialized}`)

initialize() initializes the modules: it opens the storage (Askar creates the store on the first run), starts DIDComm transports and adds OpenID4VC routes to the Express app. Then it checks the storage version. Calling initialize() on an agent that is already initialized throws.

shutdown() stops the modules and their transports and closes the storage. Afterwards agent.isInitialized is false, and you can initialize the agent again.

Storage updates​

Credo stores the version of its storage format. When you start a newer version of Credo on storage that needs an update, initialize() throws Current agent storage is not up to date. Set autoUpdateStorageOnStartup: true to run the update during initialize(), or run it yourself. Credo doesn't back up the storage first, so make a backup before you upgrade. See Updating.

With Drizzle, the database schema has its own SQL migrations, which you run separately. See Drizzle.

In this section​