Skip to content

Permissions reference

Path-bearing Bridge endpoints are validated by BridgeCore path-security specs before the handler body runs. Rejected requests never reach the filesystem or foobar2000 SDK path side effects. A path the policy refuses returns PERMISSION_DENIED; a parameter of the wrong shape or type returns INVALID_PARAMS.

Authority counts are taken from current RegisterApi path-security specs of the form { param, SecurityLevel::... } in src/api/**:

LevelSpec countMeaning
Read10Ordinary filesystem read checks
Write1Strict write destinations (config/temp style policy)
MediaRead41Media-context read checks
MediaWrite10Media-context write checks
FileWrite11General file writes (file.*)
Total7368 unique APIs

Six-level model

LevelDescriptionValidation summary
NoneNo file-path parameterNo path validation
ReadRead-only filesystem operationsBlocks system protected directories, device paths, and .. traversal
WriteWrite destinations under the strict write policyAllowed only under foobar2000 profile / temp destinations enforced by PathSecurity
MediaReadMedia metadata/content readsRead rules first; media-library / playlist trust is a fallback used only when Read rejects the path
MediaWriteMedia mutation (tags, lyrics, artwork, counts)Own chain: protected-directory blacklist, then strict write destination, media-library / playlist membership, media-library watch folders, or a sidecar sharing the directory of a trusted audio file. A non-system drive alone does not grant write access
FileWriteGeneral file writes (file.*)Own chain, not a superset of MediaWrite: blacklist, then strict write destination, media-library watch folders, non-system drive (drive letter only, UNC excluded), or media-library / playlist membership — no sidecar step. The watch-folder and non-system-drive steps are what let file.mkdir and file.write create brand-new paths

Level relationships

None < Read < Write forms the ordinary filesystem channel. None < Read < MediaRead < MediaWrite forms the media channel. Write, MediaWrite and FileWrite are independent write channels.

FileWrite is broader than MediaWrite

FileWrite accepts any path on a non-system drive, and also any path inside a media-library watch folder (including on the system drive), so it is the widest write channel currently exposed. It exists because file.* operates on arbitrary files rather than on media-context files, and applying media-write rules would make creating new files or directories impossible. Treat it as the channel to audit first when reviewing a theme.

Error response

json
{
  "success": false,
  "error": "file.read: path security denied for 'path': Access denied: protected system path",
  "code": "PERMISSION_DENIED"
}

The rejected path is never echoed back. The message names the method, the offending parameter (plus its index for array parameters, as in items[2].destination) and the policy reason, so a caller can tell which argument was refused without the host leaking a filesystem location into a payload a page may forward elsewhere.

json
{
  "success": false,
  "error": "file.read: param 'path' must be a string",
  "code": "INVALID_PARAMS"
}
javascript
const result = await fb2k.invoke('file.read', { path: somePath });
if (!result.success) {
  if (result.code === 'PERMISSION_DENIED') {
    console.warn('Path rejected by security policy:', result.error);
  } else if (result.code === 'INVALID_PARAMS') {
    console.warn('Parameter rejected before the handler ran:', result.error);
  }
}

API permission matrix

Read — filesystem read (10 specs)

APIParameterArrayNested keyNotes
artwork.getFolderImagesdirectoryRuntime authority: ArtworkApi.cpp
clipboard.writeFilespathsyesRuntime authority: ClipboardApi.cpp
file.copysourceRuntime authority: FileApi.cpp
file.copyAsyncitemsyessourceRuntime authority: FileApi.cpp
file.existspathRuntime authority: FileApi.cpp
file.getInfopathRuntime authority: FileApi.cpp
file.listpathRuntime authority: FileApi.cpp
file.readpathRuntime authority: FileApi.cpp
shell.openWithpathRuntime authority: ShellApi.cpp
shell.showInExplorerpathRuntime authority: ShellApi.cpp

Write — strict write destinations (1 specs)

APIParameterArrayNested keyNotes
http.downloadsaveToRuntime authority: HttpApi.cpp

MediaRead — media reads (41 specs)

APIParameterArrayNested keyNotes
artwork.getAvailableArtworkpathRuntime authority: ArtworkApi.cpp
artwork.getAvailableTypespathRuntime authority: ArtworkApi.cpp
artwork.getBatchpathsyesRuntime authority: ArtworkApi.cpp
artwork.getByPathpathRuntime authority: ArtworkApi.cpp
artwork.getFb2kUrlByPathpathRuntime authority: ArtworkApi.cpp
artwork.getFb2kUrlByPathBatchitemsyespathRuntime authority: ArtworkApi.cpp
artwork.getFb2kUrlByPathBatchpathsyesRuntime authority: ArtworkApi.cpp
artwork.getForTrackpathRuntime authority: ArtworkApi.cpp
artwork.getLyricspathRuntime authority: ArtworkApi.cpp
artwork.getMetadatapathRuntime authority: ArtworkApi.cpp
audio.analyzeBPMpathRuntime authority: AudioApi.cpp
audio.generateFullWaveformpathRuntime authority: AudioApi.cpp
audio.generateWaveformpathRuntime authority: AudioApi.cpp
discovery.executeContextMenuByPathtrackPathRuntime authority: DiscoveryApi.cpp
jitQueue.enqueueNexturlRuntime authority: QueueApi.cpp
jitQueue.playNowurlRuntime authority: QueueApi.cpp
jitQueue.preloadBatchurlsyesRuntime authority: QueueApi.cpp
library.getByPathpathRuntime authority: LibraryApi.cpp
lyrics.existspathRuntime authority: LyricsApi.cpp
lyrics.getpathRuntime authority: LyricsApi.cpp
metadata.probeBatchAsyncpathsyesRuntime authority: MetadataApi.cpp
metadata.readpathRuntime authority: MetadataApi.cpp
metadata.readBatchpathsyesRuntime authority: MetadataApi.cpp
metadata.readByPathpathRuntime authority: MetadataApi.cpp
metadata.readRawpathRuntime authority: MetadataApi.cpp
playback.playPathpathRuntime authority: PlaybackApi.cpp
playback.playPathspathsyesRuntime authority: PlaybackApi.cpp
playcount.getpathsyesRuntime authority: PlaycountApi.cpp
playcount.getBatchpathsyesRuntime authority: PlaycountApi.cpp
playlist.addPathspathsyesRuntime authority: PlaylistApi.cpp
playlist.addPathsAsyncpathsyesRuntime authority: PlaylistApi.cpp
playlist.addPathsSequentialpathsyesRuntime authority: PlaylistApi.cpp
playlist.replaceAllAndPlaypathsyesRuntime authority: PlaylistApi.cpp
queue.addPathspathsyesRuntime authority: QueueApi.cpp
rating.getpathRuntime authority: MetadataApi.cpp
replaygain.getpathsyesRuntime authority: ReplayGainApi.cpp
replaygain.scanpathsyesRuntime authority: ReplayGainApi.cpp
titleformat.evalpathRuntime authority: TitleformatApi.cpp
titleformat.evalBatchpathsyesRuntime authority: TitleformatApi.cpp
titleformat.evalFieldspathRuntime authority: TitleformatApi.cpp
titleformat.evalFieldsBatchpathsyesRuntime authority: TitleformatApi.cpp

MediaWrite — media mutation (10 specs)

APIParameterArrayNested keyNotes
lyrics.savepathRuntime authority: LyricsApi.cpp
metadata.embedArtworkpathRuntime authority: MetadataApi.cpp
metadata.removeEmbeddedArtpathRuntime authority: MetadataApi.cpp
metadata.removeFieldpathRuntime authority: MetadataApi.cpp
metadata.removeTagpathRuntime authority: MetadataApi.cpp
metadata.writepathRuntime authority: MetadataApi.cpp
metadata.writeBatchitemsyespathRuntime authority: MetadataApi.cpp
playcount.setpathRuntime authority: PlaycountApi.cpp
rating.setpathRuntime authority: MetadataApi.cpp
replaygain.clearpathsyesRuntime authority: ReplayGainApi.cpp

Nested array validation

metadata.writeBatch validates each object in items by reading the nested path key.

FileWrite — general file writes (11 specs)

APIParameterArrayNested keyNotes
file.copydestinationRuntime authority: FileApi.cpp
file.copyAsyncitemsyesdestinationRuntime authority: FileApi.cpp
file.deletepathRuntime authority: FileApi.cpp
file.deleteAsyncpathsyesRuntime authority: FileApi.cpp
file.mkdirpathRuntime authority: FileApi.cpp
file.movedestinationRuntime authority: FileApi.cpp
file.movesourceRuntime authority: FileApi.cpp
file.moveAsyncitemsyesdestinationRuntime authority: FileApi.cpp
file.moveAsyncitemsyessourceRuntime authority: FileApi.cpp
file.renamepathRuntime authority: FileApi.cpp
file.writepathRuntime authority: FileApi.cpp

file.copy validates source as Read and destination as FileWrite; file.move validates both endpoints as FileWrite. The asynchronous family follows the same split: file.copyAsync checks every items[].source as Read and every items[].destination as FileWrite, file.moveAsync checks both nested keys as FileWrite, and file.deleteAsync checks every entry of paths as FileWrite. Validation is fail-fast per call: one rejected entry fails the whole batch with PERMISSION_DENIED and no operation is dispatched.

Custom / non-decorator policy

These endpoints manage their own policy outside ordinary decorator specs:

APIPolicy notes
shell.execNo executable whitelist; optional cwd still goes through PathSecurity
shell.spawnNo executable whitelist; absolute executable path and cwd are path-checked
console.logLog directory restriction, reserved device names, and .log / .txt extension allowlist
playlist.insertTracksOperates on playlist handles rather than raw filesystem paths

Path security details

Common rejections

  • Device paths: \\.\... and \\?\...
  • Directory traversal containing ..
  • Empty or relative paths (absolute paths required)

Read

System-drive protected directories include:

DirectoryReason
C:\\Windows\\OS files
C:\\Program Files\\Installed programs
C:\\Program Files (x86)\\32-bit programs
C:\\ProgramData\\System configuration data

Non-system drives are generally allowed for portable / NAS media workflows under Read.

Write

Only destinations accepted by the strict write policy succeed. In practice this is the foobar2000 profile directory and the system temporary directory.

MediaRead

The Read rules run first and the path is accepted as soon as they pass. A non-system-drive path — including a UNC / NAS share — is therefore allowed without any media-library or playlist lookup.

Media-context trust is a fallback, reached only when the Read rules reject the path (in practice, a system-drive path outside the whitelist). Any one of these admits the path:

  • it is addable to the foobar2000 media library, or
  • it resolves to a media library item, or
  • it matches a playlist item. This lookup is served by a membership index that covers every playlist in full, so a genuine match is always found.

MediaWrite

MediaWrite does not delegate to the Read or MediaRead entry points; it runs its own chain. After the common rejections, a protected-directory blacklist check always applies, then the first of these to match admits the path:

  • a strict write destination (profile / temp), or
  • a path in media-library / playlist context, or
  • a path under a media-library watch folder, which covers files already on disk but not yet scanned into the library, or
  • a file in the same directory as a trusted context media file, which is how sidecar writes such as .lrc are permitted.

The blacklist is what MediaWrite adds over MediaRead: a protected system directory stays blocked even when the item does appear in a library or playlist.

Being on a non-system drive does not by itself admit a MediaWrite path. The read policy allows non-system drives, but inheriting that on the write side would mean any theme could rewrite arbitrary audio files on D: or E:.

FileWrite

FileWrite runs its own chain and is not a superset of MediaWrite. After the common rejections and the protected-directory blacklist, the first of these to match admits the path: a strict write destination (profile / temp), a media-library watch folder (is_path_addable — configuration, not membership, so it admits brand-new paths and UNC folders), a non-system drive addressed by drive letter (UNC excluded), or media-library / playlist context. MediaWrite's sidecar step is absent here.

FileWrite accepts any non-system drive

This is the widest write channel currently exposed. file.delete and file.write will therefore accept arbitrary destinations on D:, E: and so on. The allowance exists because file.mkdir and file.write create paths that by definition cannot already be in a library or playlist, so the membership steps alone would reject every call. Watch folders are different: since is_path_addable checks configuration rather than membership, new paths inside a configured folder are admitted without needing this allowance.

The test applies to the drive letter after canonicalization, not to the one in the path as passed in. If a user directory is redirected onto a non-system drive by a junction or symbolic link (for example C:\Users\<user>E:\Users\<user>, common on machines whose user profiles have been relocated), its entire subtree is evaluated in its E: form and therefore falls inside this allowance — even though the caller passed a path beginning with C:. The allowance is independent of file extension. When reviewing a theme, do not rely on the literal drive letter; check how the target machine actually redirects these directories.

The spec counts at the top of this page are maintained by hand; the RegisterApi path-security specs in the component source are the authority.