Skip to content

Send Secure Track Headers

Use this guide when your media URLs require static request headers (for example bearer tokens or tenant keys) and you need to reduce header duplication across a queue.

In 1.1.0, you can keep using Track.headers and optionally introduce Track.headerGroupId + setup({ headerGroups }) for shared declarations.

  • @ddgutierrezc/legato-contract@1.1.0
  • @ddgutierrezc/legato-capacitor@1.1.0

If you are upgrading from 1.0.0, keep reading this page and then check Migration and Versioning.

Use this decision table:

SituationRecommended field(s)
One-off token for a single trackTrack.headers only
Many tracks share the same static headersheaderGroupId + setup({ headerGroups })
Mostly shared headers, with one track-specific overrideboth (headerGroupId + headers)
Dynamic token refresh/DRM/cookie lifecycleOutside current Legato header contract

HeaderGroup is immutable after setup. Declare your reusable static headers once:

import { audioPlayer, type HeaderGroup } from '@ddgutierrezc/legato-capacitor';
const headerGroups: HeaderGroup[] = [
{
id: 'premium-us',
headers: {
Authorization: 'Bearer <shared-premium-token>',
'X-Tenant': 'us',
},
},
];
await audioPlayer.setup({ headerGroups });

Tracks can reference a shared group using headerGroupId.

import type { Track } from '@ddgutierrezc/legato-capacitor';
const tracks: Track[] = [
{
id: 'episode-42',
url: 'https://media.example.com/audio/episode-42.mp3',
type: 'progressive',
headerGroupId: 'premium-us',
},
];

Unknown group IDs are rejected at add() time, so treat group IDs as contract data and keep them stable.

4) Override group keys per track when needed

Section titled “4) Override group keys per track when needed”

Per-track headers still works and takes precedence per key:

const tracks: Track[] = [
{
id: 'episode-42',
url: 'https://media.example.com/audio/episode-42.mp3',
type: 'progressive',
headerGroupId: 'premium-us',
headers: {
Authorization: 'Bearer <episode-specific-token>', // overrides group Authorization
'X-Experiment': 'A',
},
},
];

Precedence summary:

  • group only → group headers are applied
  • track only → track headers are applied
  • both → { ...group, ...track } (track wins per key)
  • neither → no auth headers

You can mix shared-group and per-track-only entries in one queue:

const queue: Track[] = [
{
id: 'a',
url: 'https://media.example.com/a.mp3',
headerGroupId: 'premium-us',
},
{
id: 'b',
url: 'https://media.example.com/b.mp3',
headers: { Authorization: 'Bearer token-b' },
},
];
await audioPlayer.add({ tracks: queue, startIndex: 0 });
await audioPlayer.play();

6) Security boundaries and what does NOT leak

Section titled “6) Security boundaries and what does NOT leak”

Legato resolves effective request headers internally at queue admission/runtime boundaries.

  • Public snapshots/events remain public projections.
  • Do not assume internal merged request headers are exposed for inspection.
  • Keep secrets out of application logging pipelines, especially when logging track objects.

Backed by contract comments and release notes, current guarantees and non-goals are:

  • Scope: headers are applied by Android/iOS runtime media requests for that track.
  • Scope: headers are isolated per track.
  • Non-goal: DRM/license request authentication flows.
  • Non-goal: token refresh/rotation or dynamic auth callbacks.
  • Non-goal: cookie/session renewal orchestration.

If your integration requires dynamic auth lifecycle management, implement that outside the current Legato track-header model.

  1. Upgrade contract + capacitor packages to 1.1.0.
  2. Keep existing Track.headers usage unchanged (fully supported).
  3. Introduce headerGroups only where you have repeated static headers.
  4. Add tests for:
    • unknown headerGroupId fail-fast behavior
    • track-level key override precedence
    • mixed-token playlists
  5. Re-run device-level playback smoke tests on Android and iOS.

Protected tracks can be queued and played with either per-track headers, shared setup-scoped header groups, or both, while keeping advanced auth lifecycle concerns outside the current Legato contract scope.