Restricted Vault
Access-controlled storage for sensitive operational inventories: privileged-account rosters, network topology diagrams, secure-configuration workbooks, asset inventories with serial numbers. OrgAdmin-only by default, with an optional per-document allowlist for specific non-Admin readers and field-level masking for designated keys. Every read is audit-logged. Browse and author from the in-app page (TATER Security → Assets → Restricted Vault), the REST API, or MCP tools.
Why a separate surface
TATER's three existing documentation surfaces are designed for team-wide visibility:
- TATERpedia - generic methodology, shared across the org.
- Configuration Documentation - per-org system state, readable by Auditors+ at minimum.
- Business Documentation - SOPs and process docs, broadly accessible by design.
None of those are appropriate for material like a privileged-account roster, a full network topology diagram, or asset inventories listing serial numbers. Putting that content into a broadly readable surface creates an attacker roadmap and audit-trail gap. The Restricted Vault closes that gap with three guarantees:
- Read gate. OrgAdmin role required, OR the caller's Entra OID must be on the document's
accessAllowlist. Auditor and Viewer roles have NO read access whatsoever. - Every read is audit-logged. Not just create/update - every single fetch, with the caller identity, the document id, and whether the content was masked. Denied reads are also logged. This is the principal differentiator vs. the other doc surfaces.
- Field-level masking. Non-Admin allowlist readers get sensitive keys (account UPNs, serial numbers) replaced with
***-LAST4. Admins always see full content.
Using the Restricted Vault in the app
The Restricted Vault page lives in TATER Security → Assets → Restricted Vault.
Browsing and reading
- Document list. Documents you can read are shown as cards grouped by category. Badges on each card show the number of allow-listed readers beyond Org Admin, the number of masked fields, whether an attachment is present, and how many controls/risks are linked.
- Document detail. Click a card to open the document: description, the markdown Details body, and the Structured data JSON payload (pretty-printed). Linked controls and risks are listed; Org Admins also see the access allow-list and masked-field paths.
- Masking notice. Non-Admin allow-list readers see a banner ("Some fields are masked for your access level") and receive
***-LAST4values in the structured data. Org Admins always see full values. - Access audit trail. Every document detail page includes an Access audit trail table (who read the document, when, and whether access was denied), loaded from the activity log. Use Refresh to re-query.
- Access denied. Opening a document you are not allow-listed for shows an access-denied message — and the denied read is itself audit-logged.
Authoring (Org Admin)
- Create / edit. Org Admins get a + New Document button on the list page and Edit / Archive buttons on each document. The editor covers title, category, description, the markdown Details body, the structured-data JSON payload (entered as raw JSON — must be valid), linked controls/risks, masked fields, and the access allow-list.
- Masked fields. Enter one dot-path per line under
data, with*matching any array index (e.g.rows.*.serial). Masked values are shown as***-LAST4to non-Admin readers — see masking syntax below. - Access allow-list. Search your directory by name or email and add users as chips. Users on the allow-list get read-only (masked) access; leaving the list empty means Org Admins only.
- Archive. Deleting from the UI is a soft delete: the document is hidden from the list but retained — along with its audit trail — for compliance.
Document schema
| Field | Type | Notes |
|---|---|---|
title | string | Required. Up to 300 chars. |
category | string | Grouping label - "Privileged Access", "Network", "Asset Inventory", etc. |
description | string | Short purpose statement. Up to 5,000 chars. |
body | markdown | Narrative content (network diagram caption, workbook executive summary). Up to 200KB. |
data | JSON | Optional structured payload - inventory rows, account tables, etc. 1.5MB cap. |
attachment | object | Optional file pointer ({fileName, blobName, contentType, sizeBytes}). Admin-only blob fetch. |
accessAllowlist | string[] | Entra OIDs granted READ beyond OrgAdmin. Max 200. |
maskedFields | string[] | Dot-path patterns under data to mask for non-Admin readers. Max 100. |
linkedControls | string[] | Control IDs this document supports/evidences. |
linkedRisks | string[] | Risk IDs this document relates to. |
Field-level masking syntax
Each entry in maskedFields is a dot-separated path under the data blob, with * matching any array index. The masking replaces the targeted value with ***-LAST4 (last 4 characters preserved; values shorter than 5 chars become ***).
Examples for typical inventory shapes:
{
"data": {
"rows": [
{ "host": "WS-001", "serial": "SN1234567890", "user": "alice@corp.com" },
{ "host": "WS-002", "serial": "SN0987654321", "user": "bob@corp.com" }
]
},
"maskedFields": ["rows.*.serial", "rows.*.user"]
}A non-Admin allowlist reader gets back:
{
"rows": [
{ "host": "WS-001", "serial": "***-7890", "user": "***-.com" },
{ "host": "WS-002", "serial": "***-4321", "user": "***-.com" }
]
}An OrgAdmin sees the full unmasked content. The masking happens at the API layer - clients never receive the raw values for non-Admin readers, so it's safe against client-side bypass.
API reference
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /api/restricted-documents | JWT - any role | Returns docs caller can read (OrgAdmin sees all; allowlist users see entries listing their OID). Heavy body/data stripped. List call audit-logged. |
| GET | /api/restricted-documents/{id} | JWT + canRead | Full document. Audit-logged on success AND denial. Returns masked data for non-Admin allowlist readers. |
| POST | /api/restricted-documents | OrgAdmin | Create. |
| PUT | /api/restricted-documents/{id} | OrgAdmin | Update. Partial fields supported. |
| DELETE | /api/restricted-documents/{id} | OrgAdmin | Soft delete (sets status='archived' - the audit trail must remain queryable). |
MCP tools
Four tools cover the full lifecycle for agentic admins (Claude, Copilot) authoring restricted inventories from a chat:
list_restricted_vault- inventory the store. Returns titles + flags; heavy content omitted.get_restricted_document- fetch one. Every call audit-logged.create_restricted_document- Admin-only. Author from a conversation.update_restricted_document- Admin-only. Partial-update by id.
Recommended use cases
- Privileged-account roster. Body = narrative on procurement / rotation cadence;
data= JSON array of{role, upn, justification, lastReviewed};maskedFields=["accounts.*.upn"]for non-Admin allowlist readers. - Network topology diagram. Body = markdown caption + ASCII summary; attachment = the actual diagram PDF/PNG; allowlist = network engineers who aren't admins.
- M365 SCC workbook. Attachment = the .xlsx; body = executive summary; linkedControls to the controls evidenced.
- Asset inventory.
data= JSON rows with host / serial / user;maskedFields=["rows.*.serial"].
Not yet in the UI
The dedicated TATER Security page for browsing and authoring shipped (see Using the Restricted Vault in the app), including the per-document allowlist picker. Two items remain API/MCP-only for now:
- Direct file upload + blob URL generation (the schema supports the attachment pointer and the UI shows an attachment badge, but attachments are set via the API/MCP payload; full upload UX is a follow-up).
- Structured-table editor for inventory-style
datablobs (the in-app editor accepts the payload as raw JSON).