Container Manifest and Policy Configuration

Overview

A Locktera container manifest defines the access policy, DRM rules, and file metadata for a container at creation time.

The manifest is provided when encoding a container and is used to enforce:

  • Who can decrypt the container (recipients)

  • What they can do (downloadable, hidden, view/download mappings)

  • Additional access controls (password, time window, geo/IP limits, open limits)

  • How policies behave over time (drm.dynamic)

When to Use a Manifest

Use a manifest when you need to:

  • Restrict access to specific recipients or domains

  • Enforce time-limited access windows

  • Block access by IP or geolocation

  • Limit how many times a container can be opened

  • Require a password to decrypt

  • Hide or remap files in the viewer menu

  • Provide page counts or duration metadata for richer viewing behavior

If you do not need custom policies, you can use a minimal manifest with only downloadable.

Manifest Schema

Top-Level Manifest

type Manifest = {
  container: ContainerInfo;
  files?: Record<string, FileInfo>;
};, 
  • container (required) — container-wide policy configuration

  • files (optional) — per-file metadata keyed by filename

Container Policy

container.recipients

A list of email addresses allowed to decrypt the container. Supports wildcard patterns.

Supported formats:

  • example@gmail.com — single address

  • *@locktera.com — any email from a domain

  • *@* — any logged-in viewer (all authenticated users)

Example:

{
  "container": {
    "recipients": ["*@locktera.com"],
    "downloadable": false
  }
}

If recipients is omitted, access is determined by the container’s default access model (for example: owner-only or policy-defined recipients, depending on your deployment).

container.downloadable (required)

Controls whether recipients may download the container contents.

  • true — downloads allowed for viewers

  • false — downloads disabled for viewers

Note: The sender/owner can always retrieve content through authorized tooling.

Example:

{
  "container": {
    "downloadable": true
  }
}
container.password (optional)

If provided, viewers must supply this password to decrypt the container contents.

Example:

{
  "container": {
    "recipients": ["alice@company.com"],
    "downloadable": false,
    "password": "CorrectHorseBatteryStaple"
  }
}

container.drm (optional)

Defines additional access control rules that are evaluated at decryption time.

DRM Policy

drm.dynamic (optional)

Controls whether DRM rules are modifiable after encoding.

  • false (default): DRM is encrypted into the container and cannot be changed

  • true: DRM is stored in the Locktera database and can be updated by API

Use cases:

  • dynamic: false — strongest immutability; fixed policy

  • dynamic: true — enterprise controls; supports updates like revocation, time changes, new recipients, etc.

Example:

{
  "container": {
    "downloadable": false,
    "drm": {
      "dynamic": true
    }
  }
}

drm.time (optional)

Time window during which access is permitted.

  • start — before this time, decryption is denied

  • end — after this time, decryption is denied

Example:

{
  "container": {
    "recipients": ["vendor@company.com"],
    "downloadable": false,
    "drm": {
      "dynamic": true,
      "time": {
        "start": "2026-02-21T00:00:00Z",
        "end": "2026-03-21T00:00:00Z"
      }
    }
  }
}

Guideline: Use ISO-8601 timestamps in UTC (e.g., ...Z) for consistency.

drm.opens (optional)

Limits how many times each recipient can open the container.

Example:

{
  "container": {
    "recipients": ["auditor@company.com"],
    "downloadable": false,
    "drm": {
      "opens": 3
    }
  }
}

drm.ip (optional)

IP-based allow/block rules. Supported formats:

  • 192.168.1.10 (single IP)

  • 192.168.1.0/24 (CIDR subnet)

  • 192.*.1.* (wildcard)

  • 192.168.1.0-192.168.1.255 (range)

  • 192.168.1.10/255.0.255.0 (mask)

Example: allow only corporate subnet

{
  "container": {
    "recipients": ["*@company.com"],
    "downloadable": false,
    "drm": {
      "ip": {
        "allow": ["203.0.113.0/24"]
      }
    }
  }
}

Example: block a specific address

{
  "container": {
    "downloadable": false,
    "drm": {
      "ip": {
        "block": ["198.51.100.10"]
      }
    }
  }
}

Rule behavior:

  • If any allow rules exist → only allow viewers who match an allow rule

  • If only block rules exist → allow viewers unless they match a block rule

drm.geo (optional)

Geolocation-based allow/block rules using:

  • continent

  • country

  • subdivision (state/province)

  • city

Example: allow US only

{
  "container": {
    "downloadable": false,
    "drm": {
      "geo": {
        "allow": [
          { "country": "United States" }
        ]
      }
    }
  }
}

Example: block a country

{
  "container": {
    "downloadable": false,
    "drm": {
      "geo": {
        "block": [
          { "country": "Russia" }
        ]
      }
    }
  }
}

File Metadata

Per-file metadata is defined under files, keyed by filename.

files?: Record<string, FileInfo>;

FileInfo fields

  • type — MIME type (e.g., application/pdf, video/mp4)

  • pages — document page count

  • duration — media duration in seconds

  • hidden — hides file from viewer menu (default false)

  • view_instead — show a different file when selected

  • download_instead — download a different file when the download button is pressed

Example:

{
  "container": {
    "downloadable": true
  },
  "files": {
    "report.pdf": {
      "type": "application/pdf",
      "pages": 42
    },
    "raw-footage.mov": {
      "type": "video/quicktime",
      "duration": 1840,
      "hidden": true,
      "view_instead": "preview.mp4"
    },
    "preview.mp4": {
      "type": "video/mp4",
      "duration": 120,
      "download_instead": "raw-footage.mov"
    }
  }
}

Guideline: Use file remapping (view_instead, download_instead) to provide secure previews while keeping high-value originals hidden or restricted.

Manifest Quick Reference

Top-Level

Field

Type

Required

Purpose

container

ContainerInfo

Container-wide policy and DRM configuration

files

Record<string, FileInfo>

Per-file metadata, keyed by filename

container (ContainerInfo)

Field

Type

Required

Purpose

Example

recipients

string[]

Who is allowed to decrypt (supports wildcards)

["alice@company.com"], ["*@company.com"], ["*@*"]

downloadable

boolean

Whether viewers can download content

false

password

string

Password required for viewers to decrypt

"CorrectHorseBatteryStaple"

drm

Drm

Additional decryption-time rules

{ "time": {...}, "ip": {...} }

recipients address

  • example@gmail.com — exact address

  • *@locktera.com — any user from a domain

  • *@* — any authenticated viewer

container.drm (Drm)

Field

Type

Required

Purpose

Example

dynamic

boolean

Whether DRM can be updated after encode

true

geo

DrmRules<GeoRule>

Allow/block by geolocation

{ "allow": [{ "country": "United States" }] }

ip

DrmRules<string>

Allow/block by IP patterns

{ "allow": ["203.0.113.0/24"] }

opens

number

Max opens per viewer

3

time

TimeRule

Access window (start/end)

{ "start": "...Z", "end": "...Z" }

DRM Rules (DrmRules<T>)

Field

Type

Purpose

allow

T[]

If present, only viewers matching an allow rule are permitted

block

T[]

Viewers matching a block rule are denied

Evaluation rule

  • If any allow rules exist → only allow matches to allow

  • Else if only block rules exist → deny matches to block, allow all others

geo rules (GeoRule)

Field

Type

Purpose

Example

continent

string

Restrict by continent

"North America"

country

string

Restrict by country

"United States"

subdivision

string

Restrict by state/province

"Texas"

city

string

Restrict by city

"Dallas"

time rule (TimeRule)

Field

Type

Purpose

Example

start

Date

Before this time, deny decryption

"2026-02-21T00:00:00Z"

end

Date

After this time, deny decryption

"2026-03-21T00:00:00Z"

Guideline: represent timestamps as ISO-8601 UTC strings (...Z) in API requests.

files metadata (FileInfo)

Field

Type

Purpose

Example

type

string

MIME type

"application/pdf"

pages

number

Document page count

42

duration

number

Media duration (seconds)

1840

hidden

boolean

Hide from viewer menu

true

view_instead

string

Display another file when selected

"preview.pdf"

download_instead

string

Download another file instead

"preview.mp4"

Manifest Validation Rules

Required fields

container

  • container must be present.

container.downloadable

  • container.downloadable must be present and must be a boolean (true or false).

Recipient validation

container.recipients

If provided:

  • Must be a non-empty array of strings.

  • Each string must be one of:

    • exact email: user@example.com

    • domain wildcard: *@example.com

    • universal authenticated wildcard: *@*

Invalid examples

  • "@company.com" (missing local part wildcard)

  • "*company.com" (missing @)

  • "*@company" (not a valid domain format)

Behavior

  • If recipients is omitted, access defaults to your platform’s baseline policy (often owner-only unless expanded via DRM/API).

Password validation

container.passord

If provided:

  • Must be a non-empty string.

  • Recommended minimum length: 12+ characters

  • Should not be included in logs or error messages.

  • If password is set, viewers must supply it to decrypt.

DRM validation

container.drm.dynamic

If provided:

  • Must be boolean.

  • Default is false.

Behavior

  • dynamic: false → DRM rules are embedded and cannot be updated via API.

  • dynamic: true → DRM can be modified via DRM endpoints (policy updates without changing container contents).

Time rule validation

drm.time.start and drm.time.end

If provided:

  • Must be valid ISO-8601 timestamps (recommended) or valid Date values depending on implementation.

  • If both are present:

    • start must be earlier than end.

Recommended runtime behavior

  • Now < start → deny with access_not_yet_valid

  • Now > end → deny with access_expired

Opens validation

drm.opens

If provided:

  • Must be an integer.

  • Must be >= 1.

  • Recommended max (optional): set a practical ceiling (e.g., 1000) to avoid abuse.

IP rule validation

drm.ip.allow / drm.ip.block

If provided:

  • Must be an array of strings.

  • Each string must match one supported IP format:

    • 192.168.1.10 (single IP)

    • 192.168.1.0/24 (CIDR)

    • 192.*.1.* (wildcard)

    • 192.168.1.0-192.168.1.255 (range)

    • 192.168.1.10/255.0.255.0 (mask)

Evaluation

  • If any allow exists → only allow matches to allow rules.

  • If only block exists → deny matches to block rules.

Geo rule validation

drm.geo.allow / drm.geo.block

If provided:

  • Must be an array of GeoRule objects.

  • Each GeoRule may include any of:

    • continent, country, subdivision, city

  • A GeoRule with no fields set should be rejected.

Recommended matching behavior

  • A viewer matches a GeoRule if all specified fields match their resolved location.

File metadata validation

files object

If provided:

  • Must be an object keyed by filename.

  • Each key should correspond to a file included during encode (recommended strict behavior).

FileInfo.view_instead / download_instead

If provided:

  • Must reference a filename that exists in the container.

  • Prevent self-reference loops:

    • view_instead should not equal the same filename

    • chained references should not create cycles (recommended)

pages and duration

If provided:

  • Must be numbers.

  • pages must be >= 1

  • duration must be >= 0

Common Manifest Examples

1) Minimal manifest (downloads allowed)

{
  "container": {
    "downloadable": true
  }
}

2) Domain-restricted sharing + no downloads

{
  "container": {
    "recipients": ["*@company.com"],
    "downloadable": false
  }
}

3) Time-limited vendor access + IP allowlist

{
  "container": {
    "recipients": ["vendor@partner.com"],
    "downloadable": false,
    "drm": {
      "dynamic": true,
      "time": {
        "start": "2026-02-21T00:00:00Z",
        "end": "2026-03-01T00:00:00Z"
      },
      "ip": {
        "allow": ["203.0.113.0/24"]
      }
    }
  }
}

4) Fixed (non-modifiable) policy

{
  "container": {
    "recipients": ["auditor@agency.gov"],
    "downloadable": false,
    "drm": {
      "dynamic": false,
      "opens": 1
    }
  }
}

Security Notes

  • Container contents remain immutable after encoding.

  • Access is evaluated at decryption time, not at download time.

  • If drm.dynamic is enabled, policies may be updated through the DRM endpoint without modifying container contents.

  • Audit logs are generated for access attempts (authorized and denied), enabling compliance and forensic review.