Create a shared team workspace with roles, permissions, invitations, and optional SCIM provisioning.
A team knowledge base in Lifestream Vault is a shared workspace where multiple people collaborate on documents in real time. Teams have their own vaults, role-based access control, and optional automated provisioning via SCIM.
By the end of this guide you will have:
Everything is available through the Lifestream Vault web UI, the TypeScript SDK, or the lsvault CLI.
Prerequisites
A team is the top-level organisational unit. It has a name, a set of members, and owns one or more shared vaults. The user who creates a team becomes its owner automatically.
Via the UI: open Settings → Teams → New Team, enter a team name, and click Create Team.
Or use the SDK or CLI:
import { LifestreamVaultClient } from '@lifestreamdynamics/vault-sdk';
const { client } = await LifestreamVaultClient.login(
'https://vault.lifestreamdynamics.com',
'you@example.com',
'your-password',
);
const team = await client.teams.create({
name: 'Engineering',
});
console.log('Team created:', team.id);
console.log('Team name:', team.name);After the team is created, the team dashboard appears at Settings → Teams → Engineering. From here you can manage members, vaults, and settings.
Every team member is assigned one of four roles. Roles apply across all vaults owned by the team.
| Role | Description | Can Read | Can Write | Can Delete | Can Manage Members | Can Change Settings |
|---|---|---|---|---|---|---|
| viewer | Read-only access | Yes | No | No | No | No |
| editor | Can create and edit documents | Yes | Yes | No | No | No |
| admin | Can manage members and vaults | Yes | Yes | Yes | Yes | No |
| owner | Full control, including billing and deletion | Yes | Yes | Yes | Yes | Yes |
You can change a member's role at any time from Settings → Teams → [Team Name] → Members, or via the SDK/CLI.
// updateMemberRole is positional: (teamId, userId, role)
await client.teams.updateMemberRole(team.id, 'user_xyz789', 'admin');
console.log('Member role updated to admin');
// List all members with their roles — listMembers takes the teamId directly
const members = await client.teams.listMembers(team.id);
for (const member of members) {
console.log(`${member.user.displayName ?? member.user.email}: ${member.role}`);
}Send email invitations to bring people into your team. Invited users receive an email with a secure link. If they don't have a Lifestream Vault account yet, the invitation flow guides them through registration.
Each invitation specifies the email address and the role the new member will receive upon accepting.
// inviteMember is positional: (teamId, email, role).
// Role must be one of 'admin' | 'editor' | 'viewer'.
const invite = await client.teams.inviteMember(team.id, 'alice@example.com', 'editor');
console.log('Invitation created:', invite.id);
console.log('Status:', invite.status); // 'pending'
console.log('Expires at:', invite.expiresAt);
// Invite multiple people at once
const newMembers = [
{ email: 'bob@example.com', role: 'editor' as const },
{ email: 'carol@example.com', role: 'viewer' as const },
{ email: 'dan@example.com', role: 'admin' as const },
];
for (const member of newMembers) {
await client.teams.inviteMember(team.id, member.email, member.role);
console.log(`Invited ${member.email} as ${member.role}`);
}Invitations expire after 7 days by default. If a user does not accept within that window, revoke the expired invitation and create a new one (there is no resend operation). The link in the email is single-use and cannot be forwarded.
You can list and revoke pending invitations at any time. This is useful when you made a mistake in the role, or when you need to tighten access before an invitation is accepted. (There is no resend operation — revoke the stale invitation and create a new one.)
// listInvitations takes the teamId directly and returns TeamInvitation[]
const invitations = await client.teams.listInvitations(team.id);
const pending = invitations.filter((i) => i.status === 'pending');
console.log(`${pending.length} pending invitations:`);
for (const inv of pending) {
console.log(` - ${inv.email} (${inv.role}) — expires ${inv.expiresAt}`);
}
// There is no resendInvitation — to refresh an invite, revoke it and
// create a new one with inviteMember(teamId, email, role).
// Revoke an invitation before it is accepted — positional: (teamId, invitationId)
await client.teams.revokeInvitation(team.id, invitations[0].id);
console.log('Invitation revoked');SCIM 2.0 provisioning requires a Business plan. Upgrade in Settings → Subscription.
SCIM 2.0 (System for Cross-domain Identity Management) allows your Identity Provider (Okta, Azure AD, Google Workspace, etc.) to automatically provision and deprovision users in Lifestream Vault. When an employee joins your organisation, their IdP creates their Vault account automatically. When they leave, their access is revoked.
The SCIM base URL is:
https://vault.lifestreamdynamics.com/api/v1/scim/v2
Authentication uses a Bearer token that you generate in the Vault admin panel.
# The SCIM Bearer token is a static server-side environment variable.
# Set SCIM_TOKEN in your API environment and restart the server.
# Provide this token to your IdP as the SCIM bearer token.
# Generate a secure random token:
openssl rand -hex 64
# Add to your API config:
# SCIM_TOKEN=<generated value>
# Then restart the API:
pm2 restart lsvault-api
# SCIM Base URL for your IdP:
echo "https://vault.lifestreamdynamics.com/api/v1/scim/v2"SCIM Base URL: https://vault.lifestreamdynamics.com/api/v1/scim/v2
Supported SCIM operations: GET /Users, POST /Users, GET /Users/:id, PUT /Users/:id, PATCH /Users/:id, DELETE /Users/:id, GET /Groups, POST /Groups, PATCH /Groups/:id
The SCIM endpoint is authenticated with a Bearer token in the Authorization header. Your IdP handles this automatically once configured.
The team calendar aggregates all calendar events across team vaults into a single shared view. Team members can see due dates, scheduled events, and booking slots across all team-owned vaults without switching between individual vault calendars.
Via the UI: open your team dashboard and click Calendar in the sidebar.
Key features:
due: frontmatter field appears on the calendar// getCalendarEvents is positional: (teamId, { start?, end? }) -> CalendarEvent[]
const events = await client.teams.getCalendarEvents(team.id, {
start: new Date().toISOString(),
end: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // next 30 days
});
console.log(`${events.length} upcoming team events:`);
for (const event of events) {
console.log(` - [${event.startDate}] ${event.title} (vault: ${event.vaultId})`);
}
// Fetch upcoming due documents across the team — getDue(teamId, { status? })
const dueSoon = await client.teams.getDue(team.id, { status: 'upcoming' });
console.log(`${dueSoon.length} upcoming due documents`);Create an onboarding.md document in your team vault that every new member reads first. Include:
Pin it to the top of the vault with a pinned: true frontmatter field.
A common pattern is one vault per concern:
Engineering team vaults:
├── eng-docs/ # Architecture decisions, technical references
├── runbooks/ # Incident response and operational procedures
├── rfcs/ # Request-for-Comment documents for major changes
└── meeting-notes/ # Team meeting summaries and action items
Keep vault purposes narrow and well-defined. A catch-all "everything" vault becomes hard to navigate as the team grows.
Agree on naming conventions before the vault fills up:
YYYY-MM-DD-title.md for dated content (meeting notes, decisions)api-design, incident-reports)title, date, and author (or authors) in team documentsTags are searchable across all vaults a user has access to. Standardise tags like #decision, #draft, #needs-review, and #deprecated so team members can find content regardless of which vault it lives in.
Set up a webhook on the document.created and document.updated events pointing to a Slack incoming webhook URL. This way, the team sees new content in their existing communication channels without having to check the vault dashboard manually.
Schedule a monthly knowledge base grooming session where the team:
#needs-reviewYour team knowledge base is up and running. Here are some directions to explore next:
client.teams, including vault management, member management, invitations, and the team calendar