npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@bsb/config-vault

v9.7.4

Published

BSB Vault - secure managed configuration service and config loader

Readme

BSB Vault

@bsb/config-vault provides Vault, a secure managed configuration service for BSB.

It contains two plugins:

  • service-config-vault: h3 + Postgres admin UI/API.
  • config-vault: BSB config plugin that loads the latest active published config from Vault.

Runtime containers do not choose applications, groups, profiles, or versions. The Vault API key is bound server-side to an application, service group, deployment profile, and config plugin id.

Runtime

Runtime containers activate Vault as the BSB config plugin with env vars:

BSB_CONFIG_PLUGIN=config-vault
BSB_CONFIG_PLUGIN_PACKAGE=@bsb/config-vault
vaultUrl=https://vault.example.com
apiKeyId=vk_xxx
apiSecret=vs_xxx
# cacheDir=/mounted/config-vault

When a container restarts, it pulls the active published version for the API key's bound deployment profile.

Plugins may declare type-checked envOverridePaths in their createConfigSchema metadata. A deployment profile must explicitly enable environment overrides for that plugin before the runtime client accepts them. PVE infrastructure can then inject one Secret Manager-backed JSON value:

BSB_CONFIG_OVERRIDES='{"services":{"core":{"database":{"instance":"project:region:instance","name":"preview-core-123"}}}}'

The keys under services, events, and observable are configured plugin aliases. Objects merge recursively; arrays and scalar values replace the published value. Unknown plugins and undeclared paths fail startup. Override values are applied only in memory and are not sent to Vault or written to the last-known-good cache.

Service

The dedicated Vault image includes @bsb/config-vault, all BSB observable integrations, and @bsb/syslog; event transport plugins remain deployment-specific:

code.bettercorp.dev/bettercorp/service-base:node-vault-latest
betterweb/service-base:node-vault-latest

It uses the normal BSB entrypoint and configuration variables. Build it locally with:

docker build -f plugins/nodejs/config-vault/Dockerfile --build-arg BSB_BASE_IMAGE=betterweb/service-base:node-9.1.11 --build-arg BSB_PLUGIN_VERSION=9.1.11 -t betterweb/service-base:node-vault-local plugins/nodejs/config-vault
service-config-vault:
  plugin: service-config-vault
  package: "@bsb/config-vault"
  enabled: true
  config:
    host: 0.0.0.0
    port: 8080
    publicUrl: https://vault.example.com
    production: true
    databaseUrl: postgres://vault:secret@postgres:5432/vault
    masterKey: BASE64_32_BYTE_KEY
    registryUrl: https://io.bsbcode.dev
    registryToken: REGISTRY_READ_TOKEN

registryToken is optional. Set it from a deployment secret when Vault must import private plugins; the registry user needs global read permission plus publisher, package, or organization access. Vault sends it only as a bearer token on server-side registry requests.

masterKey must be a base64 encoded 32-byte key. Generate one with:

node -e "console.log(require('crypto').randomBytes(32).toString('base64'))"

Keep the value stable. If the key changes, Vault cannot decrypt configs already stored in Postgres.

First Admin Setup

On first startup, Vault logs a one-time setup code. Open /setup, enter the code, create the admin user, and confirm the password. Vault generates the TOTP enrollment secret and authenticator URI after the user is created.

Vault supports multiple administrators. Invite them from Users with a one-time setup link; each user chooses a password and enrolls at least one named TOTP/passkey pair. Login verifies password, passkey, then the TOTP paired with that exact passkey. Passkeys require HTTPS in browsers unless you are using localhost for local development, and publicUrl must match the external URL used to open Vault.

Admin UI

Vault has pages for Overview, Applications, Deployments, Plugins, Users, Audit, and Profile. Deployment profiles own config drafts, publishing, and container key create/rotate flows.

Vault stores profile config internally as the profile body:

{
  "observable": {},
  "events": {},
  "services": {}
}

The admin UI builds that body from plugin catalog entries and generated config schemas. Add a plugin, enable or disable it, then fill out the schema-derived fields instead of editing JSON. Vault validates those fields server-side, applies defaults, strips unknown keys, and rejects invalid values before encrypting drafts. Vault wraps the body under the profile name internally. Container keys are generated from the deployment profile page and the UI shows the BSB container env vars once on creation or rotation.

The admin UI validates plugin config with the portable AnyVali schema before submitting; Vault repeats validation server-side. Fields carrying AnyVali { sensitive: true, writeonly: true } metadata use write-only password controls. Runtime clients retry transient failures for 15 seconds and can use an encrypted 24-hour last-known-good cache; configure cacheDir for a custom or persistent location, or staleAllowedHours=0 to disable that fallback. Authentication, authorization, redirect, server-error, and malformed-response failures never use stale config. See the plugin docs for audit-database separation and recovery details.

Private Plugin CI Publishing

Vault accepts portable AnyVali documents from Node.js, .NET, Python, Go and Rust, including native wrapper and union aliases. Sensitive collections are masked and replaced as a whole using JSON in the password field; omitted values preserve the existing collection. Referenced schemas use this same conservative editor. This avoids leaking nested credentials or restoring a secret to the wrong array element after reordering.

Catalog identity is (pluginId, language, version). Each implementation has its own packageName and publisher credential; the same plugin/version can therefore use different packages in different languages. Upload manifests use packages[language], while CI publish requests use package[language]. Vault selects that language's coordinate and stores one catalog row per implementation. Import, sync and runtime resolution match the selected language; runtime package contains its native coordinate, not necessarily an npm name. Existing catalog rows and credentials migrate to nodejs.

| Language | Package coordinate | | --- | --- | | nodejs | npm package, e.g. @acme/reports | | csharp | NuGet package ID, e.g. Acme.Reports | | python | Python distribution, e.g. acme-reports | | go | Go import path, e.g. example.com/acme/reports/plugin | | rust | Cargo crate name, e.g. acme-reports |

The catalog also accepts java metadata; a Java host is not implemented.

Shared application profiles are validated against every active deployment profile before publication. Enable only implementations matching that deployment's host language; disabled references may point to services in another language. Deployment overrides can select the local implementation. Profile language is locked after publication. Adding a plugin creates disabled placeholders only in sibling profiles with the same language, records that language on each placeholder, and preserves existing sibling entries. Legacy profiles without a language default to Node.js.

The native-integration CI job exercises real cross-language Rabbit RPC/streams and PostgreSQL catalog migrations. See integration checks for local prerequisites.

Run the implementation's bsb plugin build, then upload one or more generated lib/schemas/{plugin-id}.plugin.json manifests on the Plugins page. These files contain the implementation language, package identity and config schema; the root bsb-plugin.json is a host discovery manifest and is not the upload file. Request, manifest and schema language declarations must agree; dotnet is normalized to csharp. A request language fills missing artifact metadata, and uploads with no language default to Node.js. Vault processes each file independently, lists its result, and creates a plugin-specific bv_p_ publish token for each new plugin. Store each token as a CI secret.

Publish the package to its native package repository and include it in the runtime image (Go/Rust plugins must be linked into the BSB host). Then run the implementation's CLI to append its generated schema to Vault:

bsb client publish \
  --target "https://vault.example.com" \
  --plugin "service-private-api" \
  --token "$VAULT_PLUGIN_TOKEN"

If the manifest declares an org other than _, also pass that value with --org; the publish organization must match the uploaded identity.

The token can publish only newer schema versions for that exact plugin id, language, org, package, and kind. An identical CI retry is accepted unchanged; an attempt to alter an existing version is rejected. Rotate the token from the plugin catalog when required—the previous token stops working immediately. Vault stores schemas and package coordinates only; runtime containers must already contain the appropriate native package or linked plugin.