Documentation contents

VCP 1 Documentation›Going Deeper

Security Guide

Transport requirements, hardening rules, and pre-launch checklists for providers, the gateway, and the client app.

Transport & baseline requirements

  1. All VCP traffic uses HTTPS with TLS 1.2 or later and a certificate chaining to a trusted CA. There is no plain-HTTP or self-signed exception: every provider is a registered publisher with a public, CA-certified origin.
  2. End-user authentication is a Bearer token in Authorization; service identification is the VCP-Service-Token header.No cookies on VCP endpoints — no cookies means no CSRF surface and no ambient credentials.
  3. There is no request-signing/HMAC layer. TLS provides integrity and confidentiality; the service token provides origin authentication of the gateway.
  4. Rate limiting is optional (per end-user token and overall per integration); when applied, respond 429 with Retry-After.

Gateway fetch hardening

The provider is untrusted input to the VC service. Every gateway fetch of a provider endpoint enforces:

RuleValue
API response max size10 MB
Connect / total timeout10 s / 30 s
RedirectsMax 3, same-origin only — cross-origin redirects abort the request.
Target addressesOnly the registered publisher origin, resolving to public IP space — connections to private/link-local/loopback ranges are refused at connect time (DNS-rebinding safe).
Content-Type checkNon-application/json bodies rejected.
JSON hardeningDepth/size-capped parser; unknown fields ignored.

Because the gateway only ever fetches hosts recorded in the publisher registry, the registry doubles as the SSRF allowlist: there is no code path that fetches an arbitrary user-typed URL. The same limits apply to manifests at submission time (max 64 KB).

Client app hardening

Devices don't speak VCP directly, but provider-originated data reaches them, so the app:

  • Renders all provider text (titles, descriptions, hints) as plain text, never as HTML/markup.
  • Accepts only https: URLs in payload fields (artwork, media, subtitles); anything else — file:, javascript:, custom schemes — is discarded.
  • Stores all provider-related credentials in the platform secure store (iOS Keychain / Android Keystore), never in logs or crash reports.
  • Namespaces provider data per-publisher locally, so two providers can never collide or overwrite each other's objects even with identical ids.

Provider checklist

  • HTTPS only; HSTS recommended.
  • Validate VCP-Service-Token on every VCP endpoint (constant-time compare); no VCP resource is public. Support two active secrets during rotation.
  • Keep the _vcp DNS TXT verification record in place for the lifetime of the registration.
  • Bearer tokens only for end users, no cookie auth on VCP endpoints.
  • Pairing: single-use short-lived codes, authenticated approval page showing device info, rate-limited attempts, ≥ 128-bit poll/refresh/access tokens.
  • Refresh-token rotation with reuse detection; per-device revocation UI.
  • Rate limiting per end-user token and overall (optional); 429 + Retry-After if applied.
  • Signed, expiring media URLs if the catalog isn't public; honor the minimum validity window; pin to VCP-Client-IP, never the gateway IP.
  • User tokens: vcpu_ prefix, ≥ 128-bit, revocable from the account page; fail invalid tokens loudly (invalid_user_token), never silently downgrade to public access.
  • Write capabilities: authorize object ownership on every request — playlist/object ids are guessable, not secrets (IDOR). Honor Idempotency-Key on creates; validate If-Match versions.
  • Treat VCP-Client, device_name, search queries, playlist titles and descriptions, and all other client-supplied strings as untrusted input — they end up rendered on your website too.

VC service (gateway) checklist

  • Per-publisher unique secrets, vcps_, ≥ 256-bit, stored in a secret manager; rotation and revocation flows in the portal.
  • Fetch hardening per the table above; the publisher registry is the only allowlist of origins the gateway will contact (SSRF containment).
  • Verify the DNS TXT challenge at registration and re-verify periodically; alert the publisher contact when the record disappears.
  • Relay, never persist, end-user provider credentials (session tokens, user tokens).
  • Rate-limit its own calls per publisher; back off on 429/5xx.
  • Alert operations on invalid_service_token responses — that indicates secret drift or revocation.

Client app checklist

  • All provider credentials in Keychain/Keystore; never logged.
  • Provider text rendered as plain text; all URLs scheme-validated.
  • Source URLs treated as ephemeral playback data: never persisted to the library, refreshed at most once automatically per playback attempt.
  • Single automatic refresh-retry on expired_token; prompt (don't loop) on invalid_user_token.
  • Offline write queue: replay in order, drop (with notice) on 401/403, never infinite-retry a rejected write.
  • Provider data namespaced per-publisher locally.

Coming soon!

We're putting the finishing touches on VClarity. It'll be on the App Store and Google Play very soon.