Skip to main content
Vaults are the ownership and permission boundary for skills in Better Skills. Every skill belongs to exactly one vault, and users access skills through vault memberships.

Vault Types

There are three vault types, each with different ownership and access semantics:

Personal

Private vault for individual users.
  • One per user
  • Owner has full write access
  • Other members have read-only access

Enterprise

Collaborative team vault.
  • Shared across team members
  • Owner and admin can write
  • Members have read-only access

System Default

Shared read-only template vault.
  • One per deployment
  • Contains default skills
  • Always read-only for users

Vault Properties

Database Schema

export const vault = pgTable("vault", {
  id: uuid("id").defaultRandom().primaryKey(),
  slug: text("slug").notNull(),
  name: text("name").notNull(),
  type: vaultTypeEnum("type").notNull(), // personal | enterprise | system_default
  color: text("color"),
  isSystemManaged: boolean("is_system_managed").notNull().default(false),
  metadata: jsonb("metadata").notNull().default(sql`'{}'::jsonb`),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

Key Fields

FieldTypeDescription
idUUIDPrimary key
slugtextGlobally unique identifier
nametextDisplay name
typeenumpersonal, enterprise, or system_default
colortextOptional UI color hint
is_system_managedbooleanGuard against user modification
metadataJSONBApplication metadata
The slug field is globally unique across all vaults, not just per-user.

Vault Memberships

Users access vaults through vault memberships, which define both permissions and preferences.

Membership Roles

Owner

Full vault control.
  • Create/edit/delete skills
  • Manage vault settings
  • Invite and remove members
  • Delete vault (enterprise only)

Admin

Write access and member management.
  • Create/edit/delete skills
  • Invite and remove members
  • Cannot delete vault

Member

Read-only access.
  • View skills and resources
  • Search and link to skills
  • Cannot modify content

Membership Schema

export const vaultMembership = pgTable("vault_membership", {
  id: uuid("id").defaultRandom().primaryKey(),
  vaultId: uuid("vault_id").notNull().references(() => vault.id),
  userId: text("user_id").notNull().references(() => user.id),
  role: vaultMembershipRoleEnum("role").notNull(), // owner | admin | member
  isEnabled: boolean("is_enabled").notNull().default(true),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});
Membership is unique per (vault_id, user_id) pair. A user can only have one role per vault.

Enabled vs Disabled Memberships

The is_enabled flag is a user preference, not a permission control:
  • Enabled (default): Vault appears in active vault list
  • Disabled: Vault is hidden from primary UI but skills remain accessible
Disabled memberships still grant access. Skills from disabled vaults appear in:
  • List and search results (with disabled status)
  • Graph traversal
  • Sync operations
Only the vault’s visibility in the dashboard changes.

Read-Only vs Writable Vaults

Write permissions are derived from vault type + membership role:

Permission Matrix

Vault TypeOwnerAdminMember
Personal✅ Write❌ Read-only❌ Read-only
Enterprise✅ Write✅ Write❌ Read-only
System Default❌ Read-only❌ Read-only❌ Read-only
System default vaults are always read-only, regardless of membership role. This ensures template skills remain stable and consistent.

Vault Invitations

Enterprise vaults use an invitation system for adding members:
export const vaultInvitation = pgTable("vault_invitation", {
  id: uuid("id").defaultRandom().primaryKey(),
  vaultId: uuid("vault_id").notNull().references(() => vault.id),
  email: text("email").notNull(),
  role: vaultMembershipRoleEnum("role").notNull().default("member"),
  status: vaultInvitationStatusEnum("status").notNull().default("pending"),
  invitedByUserId: text("invited_by_user_id").references(() => user.id),
  expiresAt: timestamp("expires_at"),
  createdAt: timestamp("created_at").defaultNow().notNull(),
  updatedAt: timestamp("updated_at").defaultNow().notNull(),
});

Invitation Lifecycle

1

Owner/Admin sends invitation

Invitation created with status: pending and target email.
2

Recipient accepts or declines

  • Accepted: Creates vault membership with specified role
  • Declined: Invitation marked as declined
3

Invitation expires or is revoked

  • Expired: Automatically marked when expires_at passes
  • Revoked: Manually canceled by owner/admin
Only one pending invitation per (vault_id, email) is allowed. This prevents invitation spam.

Vault Semantics

System Default Vault

  • Exactly one shared system_default vault exists in production
  • Contains skills seeded from resources/default-skills/
  • Marked with is_system_managed: true
  • Cannot be modified or deleted through normal operations

Personal Vaults

  • Created automatically when user signs up
  • Slug typically matches username (e.g., alice-personal)
  • Owner has exclusive write access
  • Can share with read-only members

Enterprise Vaults

  • Created explicitly by users or teams
  • Collaborative write access for owner and admins
  • Membership-driven access control
  • Can be deleted by owner

Skill Ownership

Every skill’s owner_vault_id determines:
  • Permission inheritance: Write access follows vault rules
  • Slug uniqueness: Slugs are unique per vault, not globally
  • Visibility: Skills inherit vault membership visibility
-- These skills can coexist:
INSERT INTO skill (owner_vault_id, slug, name) VALUES
  ('acme-vault-id', 'api-client', 'Acme API Client'),
  ('personal-vault-id', 'api-client', 'My API Client');

-- But this would fail (duplicate slug in same vault):
INSERT INTO skill (owner_vault_id, slug, name) VALUES
  ('acme-vault-id', 'api-client', 'Another Acme API');
-- ERROR: duplicate key violates unique constraint "skill_vault_slug_idx"

Next Steps

Skills

Learn about skill structure and SKILL.md format

Mentions

Link skills across vaults with markdown mentions

Skill Graph

Explore the multi-vault graph structure

Build docs developers (and LLMs) love