← All docs

VaultGuard Server — Community Edition

Open-source server stack for VaultGuard — an end-to-end encrypted, permission-aware sync backend for Obsidian vaults.

This repository ships the AWS infrastructure you self-host. Pair it with the VaultGuard Obsidian plugin to encrypt your team's vault, enforce per-file permissions, and revoke access cleanly when people leave.

CE is licensed under the Sustainable Use License and feature-complete for the security plane. Some operational and convenience features stay in the managed Pro plan — see What's NOT included.

Quick start

# 1. Clone and install Lambda deps
git clone <this-repo>
cd vaultguard-server/infrastructure
npm install

# 2. Build Lambda bundles
npm run build

# 3. Configure your deployment
cd ../terraform
cp environments/ce.tfvars.example environments/ce.tfvars
# Edit ce.tfvars: set stage, admin_email, sender_email, etc.

# 4. Deploy
terraform init
terraform apply -var-file=environments/ce.tfvars

After terraform apply finishes, the outputs section prints:

  • api_url — point the Obsidian plugin's API endpoint here.
  • user_pool_id, user_pool_client_id — Cognito IDs the plugin needs.
  • vault_bucket_name — S3 bucket holding encrypted vault content.
  • kms_key_arn — your customer-managed KMS key.

5. Create your first admin user

Steps 1-4 deploy the infrastructure, but the deployment lands with zero users and zero organizations. Bootstrap a single admin via the public POST /signup endpoint:

API_URL=$(terraform output -raw api_url)

curl -X POST "$API_URL/signup" \
  -H "Content-Type: application/json" \
  -d '{
    "orgName": "Acme Corp",
    "orgSlug": "acme-corp",
    "email": "you@example.com",
    "password": "YourSecurePassword123!",
    "displayName": "Your Name"
  }'

This call creates, in one transaction, the Cognito admin user (permanent password), the org-{slug} and admin Cognito groups, the organization record, a default vault, the owner VaultMember row, and a default allow-all permission rule.

For slug rules, password policy, the auto-lock behavior, and troubleshooting, see docs/SELF-HOSTING.md#create-the-first-admin-user. After this first call succeeds, Community Edition locks public signup — see Single-tenant lockdown below for re-enabling it later via vaultguard_allow_public_signup = true.

What you get

Capability Included
End-to-end file encryption (AES-256-GCM + AWS KMS)
Per-file permissions with role inheritance
Re-encryption on user offboarding
Multi-vault support per organization
Plugin allowlist enforcement
Time-bound key leases (1h default, configurable)
Cognito-based auth (federate to your IdP if desired)
Basic audit trail (GET /vaults/{vaultId}/audit/logs — last 30 days on CE)
In-Obsidian admin UI (users / permissions / settings)
Transactional email via AWS SES
Unlimited users, no seat caps

What's NOT included

These features stay in the managed Pro plan (upgrade):

Feature Why it's in Pro
Share links for internal teammates Token resolver + share-bridge SPA — Pro infrastructure
Hosted web admin panel (admin.vaultguard.cloud) React app for non-technical admins to manage users/permissions/audit without opening Obsidian
Advanced audit (dashboards, alerts, CSV export, per-user/per-file reports) Anomaly detection, scheduled reports, full retention window (CE caps audit queries at 30 days)
Stripe-backed billing Managed subscription lifecycle
Managed AWS infrastructure We run it, patch it, back it up
Managed backup and uptime targets Hosted operational program; contractual terms only by agreement
Email support targets Human help when you need it; response commitments depend on plan terms
SOC 2 / HIPAA evidence packages Enterprise evidence when available by agreement
SAML / OIDC SSO integration Federate to your IdP cleanly (Enterprise)

Share-link, billing, and web-admin endpoints exist in the CE terraform graph as inert 404 stubs — they cost effectively $0 in idle AWS spend, keep the deployment valid, and refuse all requests with a clear error. If you upgrade to a hosted Pro deployment, the same plugin install routes seamlessly to the managed backend.

Configuration

Single-tenant lockdown

CE defaults to single-tenant mode: the public POST /signup endpoint becomes a 403 once the first organization is created. This stops drive-by strangers from spinning up their own orgs on your deployment.

To re-enable public signup (for example, you're running CE as a community service), set vaultguard_allow_public_signup = true in your tfvars. Terraform passes that through as the VAULTGUARD_ALLOW_PUBLIC_SIGNUP env var on the signup Lambda function.

Audit retention

The audit log is written for every action and queryable via GET /vaults/{vaultId}/audit/logs. Default retention is 365 days, enforced by a DynamoDB TTL attribute. Change retentionDays in organization settings from the in-Obsidian admin UI or the org settings API; updates apply to new audit writes.

Advanced audit endpoints (/audit/alerts, /audit/export, /audit/user/..., /audit/file/...) are Pro-only and return 404 on CE.

Edition flag

Every Lambda checks the VAULTGUARD_EDITION env var at cold start. The terraform in this repo sets it to "community" by default; the GET /orgs/{slug}/config endpoint advertises that to the plugin so it can hide Pro-only UI surfaces (share-link buttons, advanced audit tabs, etc.) on the client side.

Do not flip this to "pro" on a CE deployment — the Pro-only handlers (shares/, billing/) ship as 404 stubs in this repo and will not gain functionality just by changing the flag.

Custom domain

Set domain_name = "vaultguard.example.com" in ce.tfvars to wire up Route 53 + ACM + API Gateway custom domain. The terraform will output the nameservers to configure at your registrar.

If you leave domain_name empty, the deployment uses the raw API Gateway and CloudFront URLs (less pretty but works).

SES sender identity

Transactional emails (invites, password resets) require a verified SES sender. After the first terraform apply:

  1. Open the AWS SES console in your deployment region.
  2. Verify the email address you set as sender_email.
  3. If you're in the SES sandbox, also verify each recipient or request production access.

Architecture

┌─────────────────┐
│ Obsidian plugin │
└────────┬────────┘
         │ HTTPS (Cognito JWT)
         ▼
┌─────────────────────┐
│   API Gateway       │
│   (REST, regional)  │
└──┬──────────────────┘
   │
   ├──► Lambda: auth          ── Cognito sessions, key leases
   ├──► Lambda: signup        ── Org bootstrap (single-tenant gated on CE)
   ├──► Lambda: vaults        ── Vault CRUD + membership
   ├──► Lambda: files         ── Encrypted file CRUD via S3 + KMS
   ├──► Lambda: permissions   ── Rule evaluation, wildcard matching
   ├──► Lambda: users         ── Lifecycle (invite/revoke), org settings
   ├──► Lambda: audit         ── Write + GET /vaults/{vaultId}/audit/logs (basic)
   ├──► Lambda: reencryption  ── Post-offboarding key + file rotation
   ├──► Lambda: email         ── SES transactional sender
   ├──► Lambda: shares        ── 404 stub (Pro)
   └──► Lambda: billing       ── 404 stub (Pro)

DynamoDB tables, S3 vault bucket, KMS CMK, SES, CloudFront (CDN for API).
WAF (rate limits, IP allowlists). Route 53 + ACM (optional custom domain).

The full HTTP contract is documented in docs/openapi.yaml. The plugin only calls the routes listed there; any backend that satisfies the spec works.

Upgrading

Upgrading from CE to managed Pro is a settings change in the Obsidian plugin, not a re-install. Point the plugin at the Pro API endpoint, sign in with your new org, and you're done. Your CE deployment can be torn down with terraform destroy (or kept running indefinitely if you prefer self-host).

Migrating data between CE and Pro is not automated — vault content lives in S3 in your account on CE and in our account on Pro. Contact support@vaultguard.cloud for a managed migration if you want to move a large team.

Support

License

Sustainable Use License. See LICENSE.

This project includes AWS SDK clients (Apache 2.0) and esbuild (MIT) as build dependencies. No proprietary code or hidden license restrictions.