UnENVerse 0.42.4
Local-first desktop secrets manager — TypeScript frontend
Loading...
Searching...
No Matches
types.ts File Reference

Data models for UnENVerse. More...

Variables

export type SecretType
 Discriminated union of all supported secret kinds.
 
export type ValueKind
 The editor/validator/preview an extra_vars value gets (Phase 24.1).
 
export type RateLimitPeriod = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'
 A single stored secret entry.
 
export interface VaultEntry
 
provider __pad0__
 Service or provider name (e.g.
 
account_name __pad1__
 Optional sub-account identifier within the same provider.
 
api_key __pad2__
 Primary secret value (API key, password, variable value, etc.).
 
api_secret __pad3__
 Secondary secret (client secret, shared secret).
 
key_id __pad4__
 Optional key identifier for disambiguation when one provider has multiple keys.
 
api_description __pad5__
 Short human-readable description of what the key is used for.
 
description __pad6__
 Longer free-text notes.
 
price_type __pad7__
 Billing model for the associated service.
 
environment __pad8__
 Deployment context this credential belongs to.
 
categories __pad9__
 Category tags this entry carries.
 
api_url __pad10__
 Base URL of the service's API.
 
callback_url __pad11__
 OAuth or webhook callback URL.
 
expires_at __pad12__
 ISO-8601 expiry date string, or null if the credential does not expire.
 
scopes __pad13__
 OAuth scopes or permission strings granted to this credential.
 
rate_limit __pad14__
 Human-readable rate-limit description (e.g.
 
rate_limit_count __pad15__
 The rate limit as a number, paired with rate_limit_period.
 
rate_limit_period __pad16__
 The window rate_limit_count applies to.
 
rate_limit_note __pad17__
 Whatever the old free-text rate_limit said when it could not be parsed into a count and a period ("varies by endpoint", "see contract").
 
purpose __pad18__
 What this credential was requested for — the justification submitted to the issuer on the application form.
 
pool __pad19__
 Name of the key pool this entry belongs to, or null for a standalone key.
 
version __pad20__
 API or SDK version this key was issued for.
 
primary_role __pad21__
 What the primary value is, for naming purposes — the ROLE segment of the generated environment-variable name.
 
secret_role __pad22__
 Role of api_secret, when the default SECRET is wrong.
 
primary_public __pad23__
 The primary value is safe to print — an OAuth client id, a Stripe pk_, an AWS access key id.
 
secret_public __pad24__
 The same, for api_secret.
 
auth_scheme __pad25__
 How this credential is sent (Phase 23, E16).
 
auth_param __pad26__
 The header or query-parameter name auth_scheme puts the value in.
 
auth_template __pad27__
 For header: the value sent, with {key} standing for the credential, e.g.
 
user_agent __pad28__
 The User-Agent this credential was minted against (Phase 23, step 5).
 
last_verified_at __pad29__
 When the user last confirmed this session still works (Phase 23, E13).
 
storage_tokens __pad30__
 Storage tokens (localStorage/sessionStorage) a web session needs alongside its cookies (Phase 24.5).
 
storage __pad31__
 
key __pad32__
 
value __pad33__
 
header_recipe __pad34__
 How a derived header is built for this session — the *arr family's X-Api-Key, YouTube's SAPISIDHASH, LinkedIn's csrf header copied off a cookie.
 
source __pad35__
 
static_value __pad36__
 
cookie_name __pad37__
 
strip_quotes __pad38__
 
derived_id __pad39__
 
acts_as __pad40__
 API-key taxonomy — orthogonal axes (Phase 24.5), auto-filled from issuer prefixes by enrich (gaps only, per the existing rule) and never enforced: ‘exposure: 'publishable’*suggests*primary_public`, never sets it, so a misdetected prefix cannot make redaction print less.
 
reach __pad41__
 
exposure __pad42__
 
issuer_kind __pad43__
 
access __pad44__
 
console_url __pad45__
 Where to revoke or rotate this credential.
 
ip_allowlist __pad46__
 
last_copied_name __pad47__
 The generated variable name this entry was last copied or exported under (Phase 23, step 6).
 
blob_data __pad48__
 The contents of a file-shaped credential (Phase 23, E17).
 
mount_path __pad49__
 Where the consumer expects to find this credential on disk (E17).
 
composite_template __pad50__
 The shape of a composite entry's rendered value, holes and all — https://.../{mailbox_id}@.../{calendar_key}/calendar.ics.
 
composite_kind __pad51__
 What kind of thing a composite template is, which decides its encoding and whether Open is offered.
 
bundle_id __pad52__
 The bundle entry's id this entry is a member of (Phase 24.1).
 
bundle_slot __pad53__
 This member's slot name within its bundle — "discord", "web", "v3".
 
bundle_order __pad54__
 Sort key with gaps, never identity (invariant 1) — the same shape as a pool cursor position, not an array index.
 
bundle_primary __pad55__
 On the bundle entry itself (‘secretType === 'bundle’): which member's id the card's main Copy button copies.
 
label __pad56__
 A short namespace token inserted into generated environment-variable names after the version — SPOTIFY_V2_GAME_ID.
 
custom_icon __pad57__
 Simple Icons slug for a custom provider icon, or null to use auto-detection.
 
details __pad58__
 Additional metadata or usage notes.
 
version_history __pad59__
 Snapshots of previous api_key values.
 
saved_at __pad60__
 
projectIds __pad61__
 Ids of the projects this entry belongs to.
 
secretType __pad62__
 Discriminates which secret-type-specific fields and form layout apply.
 
username __pad63__
 Username for password or ssh_key entries.
 
email __pad64__
 Email associated with this credential.
 
certificate_data __pad65__
 PEM-encoded certificate content (fullchain).
 
cert_key_data __pad66__
 Private key PEM paired with this certificate.
 
cert_issuer __pad67__
 Issuer / CA that provided the certificate (e.g.
 
blob_ref __pad68__
 File-system path or reference to a credential file.
 
env_var_subtype __pad69__
 Sub-type hint for env_var entries (used for display and filtering).
 
created_at __pad70__
 ISO-8601 timestamp of when this entry was first written to the vault.
 
last_rotated_at __pad71__
 ISO-8601 timestamp of the last manual rotation (set via "Mark as rotated").
 
rotation_days __pad72__
 Rotation cadence in days.
 
compromised __pad73__
 Marks a credential as known-leaked / emergency-rotate.
 
tags __pad74__
 Free-form tags for quick cross-cutting labelling (separate from categories/projects).
 
pinned __pad75__
 When true the entry floats to the top of all filtered views.
 
extra_vars __pad76__
 Extra named fields beyond the fixed schema (e.g.
 
value __pad77__
 
secret __pad78__
 
 __pad79__
 Opt this value out of redaction everywhere (Phase 23, E5).
 
role __pad80__
 Overrides the env-name segment derived from key (Phase 23 design, finally added in 24.1 alongside composite parts — a part's placeholder name and its generated env-name segment are not always the same word).
 
tier __pad81__
 Which copy profile includes this variable.
 
kind __pad82__
 The editor/validator/preview this value gets in the form (Phase 24.1).
 
attrs __pad83__
 Per-cookie attributes, filled by the paste parser (Phase 23, E14).
 
path __pad84__
 
secure __pad85__
 
http_only __pad86__
 
expires __pad87__
 Unix seconds.
 
totp_secret __pad88__
 Base32 TOTP seed this credential's service issued — the authenticator secret, from which UnENVerse generates the six digits you type into that service's login form.
 
totp_algorithm __pad89__
 HMAC the issuer generates with.
 
totp_digits __pad90__
 Digits in the generated code.
 
totp_period __pad91__
 Seconds a code is valid for.
 
totp_kind __pad92__
 What the seed is: totp (time-based, the default when absent), hotp (counter-based) or steam (Steam Guard's five characters).
 
totp_counter __pad93__
 The next counter an hotp seed will use.
 
env_prefixes __pad94__
 Env-var prefixes added by services that consume this credential.
 
export interface Project
 A hierarchical category node (UI label: "Category").
 
name __pad95__
 Display name.
 
description __pad96__
 Optional description shown as a tooltip in the category tree.
 
project_type __pad97__
 High-level type of the project — drives the special config view.
 
chunks __pad98__
 Structured config chunks for WireGuard or Docker projects.
 
export type ChunkFieldType
 Sub-type of a field in a structured config chunk.
 
export interface ChunkField
 A single field within a structured config chunk (WireGuard section, Docker service, etc.).
 
value __pad99__
 Raw value or "${REF_NAME}" syntax to reference a vault env_var entry.
 
field_type __pad100__
 How this field is categorised and exported.
 
ref_name __pad101__
 If non-null, this field's value is resolved from the vault entry where provider === ref_name and ‘secretType === 'env_var’`.
 
secret __pad102__
 When true the value is masked in the UI.
 
description __pad103__
 Optional description / comment for this field.
 
export type ChunkType
 Type of a structured config chunk — determines field schema and export format.
 
export interface SecretChunk
 A named section within a structured project config.
 
name __pad104__
 Display name ("Interface", "Peer — office", "navidrome service", etc.).
 
chunk_type __pad105__
 
fields __pad106__
 
notes __pad107__
 Optional freetext notes shown under the chunk header.
 
disabled __pad108__
 When true the chunk is greyed-out and excluded from exports.
 
last_copied_snapshot __pad109__
 Snapshot of resolved env output (KEY→value hash map) at last copy — powers "changed since last copy".
 
last_copied_snapshot string
 
last_copied_at __pad110__
 ISO-8601 timestamp of the last resolved copy.
 
export type ProjectType
 High-level type of a project — drives the special config view.
 
export const STABLE_PROJECT_TYPES
 Project types that have actually been exercised end to end.
 
export const wireguard
 
export const docker
 
export const nginx
 
export const kubernetes
 
export const ssh_config
 
export const traefik
 
export const apache
 
export const haproxy
 
export const ansible
 
export const postgres
 

Detailed Description

Data models for UnENVerse.

@description Defines the structure of vault entries, projects, and application settings shared between the TypeScript frontend and the persisted JSON format. These types mirror the JSON blob stored in the SQLCipher vault table.

Variable Documentation

◆ SecretType

export type SecretType

Discriminated union of all supported secret kinds.

The active variant controls which form fields are shown and which card labels are used. api_key is the default for legacy entries.

  • api_key – Standard API key or bearer token.
  • password – Service login password.
  • certificate – PEM-encoded TLS/SSL certificate.
  • env_var – Shell environment variable (name + value pair).
  • connection_string – Database or service connection URI.
  • ssh_key – SSH private key or host fingerprint.
  • file_blob – Reference path to an on-disk credential file.

◆ ValueKind

export type ValueKind

The editor/validator/preview an extra_vars value gets (Phase 24.1).

Never a storage change — see the field doc on extra_vars[].kind. Core, colour, template and large-id/bitfield groups landed in 24.1 (the Discord acceptance fixture needs them); the dev-format group is deferred to 24.5, where it lands beside the secret-type registry the descriptors belong to.

◆ RateLimitPeriod

export type RateLimitPeriod = 'second' | 'minute' | 'hour' | 'day' | 'week' | 'month' | 'year'

A single stored secret entry.

api_key holds the primary secret value regardless of secretType. Fields irrelevant to a given type are null / undefined and hidden in the UI. Every entry always belongs to at least the "Universal" category (projectIds). The window a VaultEntry.rate_limit_count applies to.

second and minute are here even though most published limits are hourly or daily, because the ones that bite in practice are per-second burst caps — and because the free-text values already in vaults are overwhelmingly "n/min", which has to survive migration as something.

◆ VaultEntry

export interface VaultEntry
Initial value:
{
id?: string

◆ __pad0__

provider __pad0__

Service or provider name (e.g.

"GitHub", "DATABASE_URL"). Always required.

◆ __pad1__

account_name __pad1__

Optional sub-account identifier within the same provider.

◆ __pad2__

api_key __pad2__

Primary secret value (API key, password, variable value, etc.).

◆ __pad3__

api_secret __pad3__

Secondary secret (client secret, shared secret).

Used by api_key type only.

◆ __pad4__

key_id __pad4__

Optional key identifier for disambiguation when one provider has multiple keys.

◆ __pad5__

api_description __pad5__

Short human-readable description of what the key is used for.

◆ __pad6__

description __pad6__

Longer free-text notes.

◆ __pad7__

price_type __pad7__

Billing model for the associated service.

◆ __pad8__

environment __pad8__

Deployment context this credential belongs to.

◆ __pad9__

categories __pad9__

Category tags this entry carries.

Backed by VaultData.user_categories, shown in the sidebar's "Categories" section, and matched by RBAC scope_type: "category".

(An earlier comment here claimed these were labelled "Projects" in the UI. They are not — the data names, the sidebar headings and the RBAC scope names all agree. Only the DOM element ids were crossed, and those have since been renamed.)

◆ __pad10__

api_url __pad10__

Base URL of the service's API.

◆ __pad11__

callback_url __pad11__

OAuth or webhook callback URL.

◆ __pad12__

expires_at __pad12__

ISO-8601 expiry date string, or null if the credential does not expire.

◆ __pad13__

scopes __pad13__

OAuth scopes or permission strings granted to this credential.

◆ __pad14__

rate_limit __pad14__

Human-readable rate-limit description (e.g.

"100 req/min").

Legacy, and kept deliberately. The structured pair below (rate_limit_count + rate_limit_period) is what the UI and the health scan read. This string is still written on save, rendered from the pair when the pair is set, so a vault edited by a current build stays readable to an older one — and so an entry whose limit was never expressible as <n> per <period> ("varies by endpoint") keeps the text the user wrote.

Never parse this field directly. parseRateLimit() in utils.ts is the one reader, and unv-cli/src/ratelimit.rs is its twin.

◆ __pad15__

rate_limit_count __pad15__

The rate limit as a number, paired with rate_limit_period.

null means "not known", which is not the same as 0 — a limit of zero would mean the credential is useless, and some services really do issue suspended keys. Both halves must be set for the limit to be considered structured; a count without a period is meaningless and is dropped on read.

◆ __pad16__

rate_limit_period __pad16__

The window rate_limit_count applies to.

◆ __pad17__

rate_limit_note __pad17__

Whatever the old free-text rate_limit said when it could not be parsed into a count and a period ("varies by endpoint", "see contract").

Kept rather than discarded: the text was written by a human who knew something the schema does not express, and silently dropping it on the first save under a new version is data loss the user never asked for.

◆ __pad18__

purpose __pad18__

What this credential was requested for — the justification submitted to the issuer on the application form.

Distinct from api_description (what it is) and details (notes to self). This is the sentence you will be held to if the issuer asks why you have the key, and it is worth recording at the moment you write it, because six months later nobody remembers.

◆ __pad19__

pool __pad19__

Name of the key pool this entry belongs to, or null for a standalone key.

Several entries sharing a pool name are interchangeable credentials for the same service, held so that a caller can swap between them when one is rate limited. Membership is explicit: two keys for the same provider do not pool automatically, because unv get GitHub refusing an ambiguous match is the behaviour that stops a command from silently acting on a credential the caller did not mean (see the invariants in CLAUDE.md).

Swap state — cursor, cooldowns, use counts — is deliberately NOT stored here. It lives in a per-machine sidecar; see unv-cli/src/pool.rs.

◆ __pad20__

version __pad20__

API or SDK version this key was issued for.

◆ __pad21__

primary_role __pad21__

What the primary value is, for naming purposes — the ROLE segment of the generated environment-variable name.

Absent keeps the bare name. Every .env already deployed from this app names the primary value PROVIDER=, so defaulting this to ‘'key’` would rename that variable for every existing entry on the next copy, and the user would find out when a service came back up without its credentials.

The vocabulary is open, not a closed union past the six presets: issuers invent names (app_id, merchant_id, tenant), and a closed union means the escape hatch is extra_vars — which is the fragmentation Phase 23 exists to remove.

◆ __pad22__

secret_role __pad22__

Role of api_secret, when the default SECRET is wrong.

◆ __pad23__

primary_public __pad23__

The primary value is safe to print — an OAuth client id, a Stripe pk_, an AWS access key id.

Opts api_key out of redaction everywhere (E5).

◆ __pad24__

secret_public __pad24__

The same, for api_secret.

Rare, but an issuer's "secret" is sometimes public.

◆ __pad25__

auth_scheme __pad25__

How this credential is sent (Phase 23, E16).

How to send it is part of the credential and was nowhere in the model: two entries that look identical are used completely differently, and the user had to remember which service wants X-Api-Key, which wants Authorization: Bearer, and which wants it in the query string.

This is what turns a stored string into a working request, and it is what the curl and cookie exports need anyway.

◆ __pad26__

auth_param __pad26__

The header or query-parameter name auth_scheme puts the value in.

Meaningless for bearer (the header is fixed) and for basic (the value is the password half). Defaults to X-Api-Key for header and api_key for query.

◆ __pad27__

auth_template __pad27__

For header: the value sent, with {key} standing for the credential, e.g.

MediaBrowser Token="{key}". Absent means the credential on its own.

◆ __pad28__

user_agent __pad28__

The User-Agent this credential was minted against (Phase 23, step 5).

A session cookie replayed without the matching User-Agent usually 401s, so this is not optional metadata — it is half of the credential.

It is also a fingerprint, so it never appears in basic metadata comments or anywhere the redacting resolver writes.

◆ __pad29__

last_verified_at __pad29__

When the user last confirmed this session still works (Phase 23, E13).

Rotation is meaningless for a session credential — "rotate" means "log in again in a browser", which this app cannot do — so a cookie flagged never-rotated and overdue forever is a nag with no available fix, and a nag with no available fix trains people to ignore the health scan, which costs more than it gains. This is the check that is actionable instead.

◆ __pad30__

storage_tokens __pad30__

Storage tokens (localStorage/sessionStorage) a web session needs alongside its cookies (Phase 24.5).

cookie generalises from "a cookie jar" to "a web session" without a field rename — every Phase 23 vault still uses the cookie id, only the label reads "Web session" now.

Never in basic metadata or a redacting resolver's output — a storage token is exactly as much a live credential as the cookies beside it.

◆ __pad31__

storage __pad31__

◆ __pad32__

key __pad32__

◆ __pad33__

value __pad33__

◆ __pad34__

header_recipe __pad34__

How a derived header is built for this session — the *arr family's X-Api-Key, YouTube's SAPISIDHASH, LinkedIn's csrf header copied off a cookie.

‘source: 'derived’` headers are computed at copy time, so a copied header is only good briefly; the UI that renders one says so.

◆ __pad35__

source __pad35__

◆ __pad36__

static_value __pad36__

◆ __pad37__

cookie_name __pad37__

◆ __pad38__

strip_quotes __pad38__

◆ __pad39__

derived_id __pad39__

◆ __pad40__

acts_as __pad40__

API-key taxonomy — orthogonal axes (Phase 24.5), auto-filled from issuer prefixes by enrich (gaps only, per the existing rule) and never enforced: ‘exposure: 'publishable’*suggests*primary_public`, never sets it, so a misdetected prefix cannot make redaction print less.

◆ __pad41__

reach __pad41__

◆ __pad42__

exposure __pad42__

◆ __pad43__

issuer_kind __pad43__

◆ __pad44__

access __pad44__

◆ __pad45__

console_url __pad45__

Where to revoke or rotate this credential.

◆ __pad46__

ip_allowlist __pad46__

◆ __pad47__

last_copied_name __pad47__

The generated variable name this entry was last copied or exported under (Phase 23, step 6).

The only new persisted state this phase adds, and it exists for one finding: renaming a provider, version or label silently renames every variable the entry generates, and the .env already sitting on a server keeps the old name. That is the renameProviderRefs() problem with a wider blast radius, because the stale reference is not in the vault at all — it is in a file on a machine nobody is looking at.

Non-secret: a variable name is not a credential.

◆ __pad48__

blob_data __pad48__

The contents of a file-shaped credential (Phase 23, E17).

A GCP service-account JSON, an Apple .p8, an mTLS bundle and a kubeconfig are consumed by pointing at them: GOOGLE_APPLICATION_CREDENTIALS=/etc/gcp/sa.json. Copying the contents to a clipboard produces something no consumer wants, and pasting a 2 KB JSON blob into a .env produces a variable the library tries to open as a path.

blob_ref holds only a path, so a fresh machine has the reference and not the credential; certificate_data holds the PEM but has nowhere to write it. This is the storage half, and mount_path is the delivery half.

Capped — see BLOB_MAX_BYTES. A service-account JSON is ~2.3 KB and an embedded icon is already allowed 96 KB, so storing content is fine; a kubeconfig with several clusters or a full chain bundle is not the same promise, and silently storing a truncated credential is worse than refusing.

◆ __pad49__

mount_path __pad49__

Where the consumer expects to find this credential on disk (E17).

The delivery half of a file-shaped entry: unv file write materialises to it, ${Entry/path} renders it, and unv exec writes a temp file and removes it afterwards. Non-secret — it is a path, not a credential.

◆ __pad50__

composite_template __pad50__

The shape of a composite entry's rendered value, holes and all — https://.../{mailbox_id}@.../{calendar_key}/calendar.ics.

Printed, not masked (it is the holes, not the values) — it must still be added to PUBLIC_FIELDS deliberately, since fail-closed redaction would otherwise mask it. See src/ts/composite.ts for rendering.

◆ __pad51__

composite_kind __pad51__

What kind of thing a composite template is, which decides its encoding and whether Open is offered.

Open past the four presets — the same open-vocabulary reasoning as primary_role.

◆ __pad52__

bundle_id __pad52__

The bundle entry's id this entry is a member of (Phase 24.1).

Membership is stored once, on the member — the same shape as pool — so an older build that deletes the bundle entry cannot leave two disagreeing copies of "is this bundled". null/absent means unbundled.

◆ __pad53__

bundle_slot __pad53__

This member's slot name within its bundle — "discord", "web", "v3".

Validated like label (^[A-Za-z0-9][A-Za-z0-9_-]{0,23}$), unique within the bundle. Addressed as ${bundle:Name/slot} and {slot.field} inside the bundle's own templates.

◆ __pad54__

bundle_order __pad54__

Sort key with gaps, never identity (invariant 1) — the same shape as a pool cursor position, not an array index.

◆ __pad55__

bundle_primary __pad55__

On the bundle entry itself (‘secretType === 'bundle’): which member's id the card's main Copy button copies.

null` means nothing is copyable from the collapsed card yet.

◆ __pad56__

label __pad56__

A short namespace token inserted into generated environment-variable names after the version — SPOTIFY_V2_GAME_ID.

Not account_name. Account names in real vaults are email addresses, and SPOTIFY_DARTHDEMONO_GMAIL_COM_ID is not what anyone wants. Validated at the form to ^[A-Za-z0-9][A-Za-z0-9_-]{0,23}$ so it is always usable as a segment.

◆ __pad57__

custom_icon __pad57__

Simple Icons slug for a custom provider icon, or null to use auto-detection.

◆ __pad58__

details __pad58__

Additional metadata or usage notes.

◆ __pad59__

version_history __pad59__

Snapshots of previous api_key values.

Prepended automatically on save when the value changes.

◆ __pad60__

saved_at __pad60__

◆ __pad61__

projectIds __pad61__

Ids of the projects this entry belongs to.

Backed by VaultData.projects, shown in the sidebar's "Projects" section, and matched by RBAC scope_type: "project".

Always contains "Universal" — the catch-all every entry carries. A specific project grant is never satisfied by it.

◆ __pad62__

secretType __pad62__

Discriminates which secret-type-specific fields and form layout apply.

◆ __pad63__

username __pad63__

Username for password or ssh_key entries.

◆ __pad64__

email __pad64__

Email associated with this credential.

◆ __pad65__

certificate_data __pad65__

PEM-encoded certificate content (fullchain).

certificate entries only.

◆ __pad66__

cert_key_data __pad66__

Private key PEM paired with this certificate.

◆ __pad67__

cert_issuer __pad67__

Issuer / CA that provided the certificate (e.g.

"Let's Encrypt", "Google", "EnvV"). certificate entries only.

◆ __pad68__

blob_ref __pad68__

File-system path or reference to a credential file.

file_blob entries only.

◆ __pad69__

env_var_subtype __pad69__

Sub-type hint for env_var entries (used for display and filtering).

◆ __pad70__

created_at __pad70__

ISO-8601 timestamp of when this entry was first written to the vault.

Optional because vaults written before this field existed have no such record, and there is no honest way to invent one. backfillCreatedAt() in state.ts infers a date for those from evidence already in the vault — the oldest version_history snapshot, or the earliest audit row naming the entry — and leaves it unset when there is none. An entry with no created_at renders as "unknown" and is omitted from the calendar feed, which is the truthful answer: stamping "today" onto every pre-existing secret would make the timeline panel and every exported .ics repeat a date nobody chose.

Never rewritten on edit. This is a creation date, not a modification date; version_history[0].saved_at is where "when did it last change" lives.

◆ __pad71__

last_rotated_at __pad71__

ISO-8601 timestamp of the last manual rotation (set via "Mark as rotated").

◆ __pad72__

rotation_days __pad72__

Rotation cadence in days.

When set, health scan flags entries overdue since last_rotated_at.

◆ __pad73__

compromised __pad73__

Marks a credential as known-leaked / emergency-rotate.

Surfaces as a critical health issue.

◆ __pad74__

tags __pad74__

Free-form tags for quick cross-cutting labelling (separate from categories/projects).

◆ __pad75__

pinned __pad75__

When true the entry floats to the top of all filtered views.

◆ __pad76__

extra_vars __pad76__

Extra named fields beyond the fixed schema (e.g.

db, port, host for database entries).

◆ __pad77__

value __pad77__

◆ __pad78__

secret __pad78__

◆ __pad79__

__pad79__

Opt this value out of redaction everywhere (Phase 23, E5).

extra_vars are masked by default. public is per value and never per type: a client id, a region, an account SID and a publishable key are each safe to print and the secret beside them is not. Without it the basic copy profile is either useless (everything masked) or unsafe (nothing).

◆ __pad80__

role __pad80__

Overrides the env-name segment derived from key (Phase 23 design, finally added in 24.1 alongside composite parts — a part's placeholder name and its generated env-name segment are not always the same word).

◆ __pad81__

tier __pad81__

Which copy profile includes this variable.

Absent means ‘'basic’`.

◆ __pad82__

kind __pad82__

The editor/validator/preview this value gets in the form (Phase 24.1).

Storage never changes: every value is a string end to end, whatever the kind. A kind is data about how to edit the string, never a coercion — hex_int and large_id both stay strings so a JSON export can quote a large id without a JS number silently rounding it.

◆ __pad83__

attrs __pad83__

Per-cookie attributes, filled by the paste parser (Phase 23, E14).

cookies.txt needs a domain, an include-subdomains flag, a path, a secure flag and an expiry for every cookie. A DevTools "Copy all as JSON" and a pasted cookies.txt both carry them; a bare document.cookie string does not, and the export is refused in that case rather than writing a file yt-dlp silently ignores.

◆ __pad84__

path __pad84__

◆ __pad85__

secure __pad85__

◆ __pad86__

http_only __pad86__

◆ __pad87__

expires __pad87__

Unix seconds.

0 is a session cookie.

◆ __pad88__

totp_secret __pad88__

Base32 TOTP seed this credential's service issued — the authenticator secret, from which UnENVerse generates the six digits you type into that service's login form.

This is the reverse of the Phase 19 TOTP, which is a second factor on UnENVerse's own sub-user login and lives in the users table, never here. Nothing reads both.

Stored normalised: uppercase base32, no spaces, dashes or padding, so two entries holding the same seed typed differently are byte-identical and fingerprint the same. A pasted otpauth:// URI is split into this field and the three below at the form rather than stored whole — the URI is a container, and keeping it would mean a second field that also holds the secret and has to be masked everywhere this one is.

It is a secret in every sense the vault means: masked by maskKeysByDefault, in SECRET_FIELDS for CLI redaction, and snapshot into version_history on change.

◆ __pad89__

totp_algorithm __pad89__

HMAC the issuer generates with.

Absent means SHA-1, which is what otpauth:// means when it omits the parameter and what almost every issuer uses. Written only when the issuer said something else — a field that reads "SHA1" on every entry cannot be told apart from a defaulted one.

◆ __pad90__

totp_digits __pad90__

Digits in the generated code.

Absent means 6.

◆ __pad91__

totp_period __pad91__

Seconds a code is valid for.

Absent means 30.

◆ __pad92__

totp_kind __pad92__

What the seed is: totp (time-based, the default when absent), hotp (counter-based) or steam (Steam Guard's five characters).

Phase 22.2.

◆ __pad93__

totp_counter __pad93__

The next counter an hotp seed will use.

Written whenever the seed is counter-based, zero included — zero is a real position, not an absent one — and removed for the other kinds. It is state rather than configuration, which is why advancing it is an explicit action.

◆ __pad94__

env_prefixes __pad94__

Env-var prefixes added by services that consume this credential.

For Key type: e.g. ["ND", "SPOTIFYD"] means Navidrome uses ND_LASTFM_APIKEY. For Chunk type: the first prefix IS the chunk's env-namespace identifier (e.g. ["AM"] for AM_JWT_SECRET).

◆ Project

export interface Project
Initial value:
{
id: string

A hierarchical category node (UI label: "Category").

Slash-delimited names encode a virtual tree: "Cloud/AWS" is a child of "Cloud". The reserved entry with id === "Universal" is a catch-all; every entry belongs to it.

◆ __pad95__

name __pad95__

Display name.

Slash-segments indicate hierarchy (e.g. "Cloud/AWS").

◆ __pad96__

description __pad96__

Optional description shown as a tooltip in the category tree.

◆ __pad97__

project_type __pad97__

High-level type of the project — drives the special config view.

◆ __pad98__

chunks __pad98__

Structured config chunks for WireGuard or Docker projects.

◆ ChunkFieldType

export type ChunkFieldType
Initial value:
=
| 'var'
| 'env_var'
| 'secret'
| 'list'
| 'multiline'
| 'port'
| 'user_id'
| 'subnet'
| 'ip'
| 'endpoint'
| 'volume_mount'
| 'cert'

Sub-type of a field in a structured config chunk.

◆ ChunkField

export interface ChunkField
Initial value:
{
key: string
let key
Definition bundle-import.ts:252

A single field within a structured config chunk (WireGuard section, Docker service, etc.).

◆ __pad99__

value __pad99__

Raw value or "${REF_NAME}" syntax to reference a vault env_var entry.

◆ __pad100__

field_type __pad100__

How this field is categorised and exported.

◆ __pad101__

ref_name __pad101__

If non-null, this field's value is resolved from the vault entry where provider === ref_name and ‘secretType === 'env_var’`.

◆ __pad102__

secret __pad102__

When true the value is masked in the UI.

◆ __pad103__

description __pad103__

Optional description / comment for this field.

◆ ChunkType

export type ChunkType

Type of a structured config chunk — determines field schema and export format.

◆ SecretChunk

export interface SecretChunk
Initial value:
{
id: string

A named section within a structured project config.

◆ __pad104__

name __pad104__

Display name ("Interface", "Peer — office", "navidrome service", etc.).

◆ __pad105__

chunk_type __pad105__

◆ __pad106__

fields __pad106__

◆ __pad107__

notes __pad107__

Optional freetext notes shown under the chunk header.

◆ __pad108__

disabled __pad108__

When true the chunk is greyed-out and excluded from exports.

◆ __pad109__

last_copied_snapshot __pad109__

Snapshot of resolved env output (KEY→value hash map) at last copy — powers "changed since last copy".

◆ string

last_copied_snapshot string

◆ __pad110__

last_copied_at __pad110__

ISO-8601 timestamp of the last resolved copy.

◆ ProjectType

export type ProjectType
Initial value:
=
| 'generic'
| 'wireguard'
| 'docker'
| 'nginx'
| 'kubernetes'
| 'ssh_config'
| 'traefik'
| 'apache'
| 'haproxy'
| 'ansible'
| 'postgres'
| 'prometheus'
| 'grafana'
| 'homepage'

High-level type of a project — drives the special config view.

◆ STABLE_PROJECT_TYPES

export const STABLE_PROJECT_TYPES

Project types that have actually been exercised end to end.

A type earns its place here by having its generated config accepted by the software it targets, not by round-tripping through a parser we also wrote. Phase 18 ran that matrix (.github/workflows/exporters.yml, and locally against containers) and every type below passed with a control case proving the validator rejects nonsense:

type evidence
wireguard round-trip through parseWgConf
docker Compose schema + .env pairing
nginx round-trip through parseNginxConf
kubernetes applied to a real k3s cluster; value decoded back out of it
ssh_config parsed by OpenSSH ssh -G
traefik loaded by Traefik v3; router and middleware report enabled
apache httpd -t → Syntax OK
haproxy haproxy -c → exit 0
ansible ansible-playbook --syntax-check → exit 0
postgres a real server authenticated using only the generated .pgpass

Two of them only passed after a fix the validation itself found: six exporters never resolved ${ref} (invariant 5), and exportAnsible emitted a mapping followed by a sequence — not valid YAML in any parser.

The rule for adding one: nothing goes in this list on the strength of a fixture alone. A fixture proves we agree with ourselves.

◆ wireguard

export const wireguard

◆ docker

export const docker

◆ nginx

export const nginx

◆ kubernetes

export const kubernetes

◆ ssh_config

export const ssh_config

◆ traefik

export const traefik

◆ apache

export const apache

◆ haproxy

export const haproxy

◆ ansible

export const ansible

◆ postgres

export const postgres