FEATURE SPOTLIGHT: File-Based Rule Replacements¶
This document describes how to keep sensitive values (passwords, API keys, tokens)
out of FUZZY_MAP_pre / FUZZY_MAP source code and Git history by loading the
replacement text from a separate file at runtime instead of hardcoding it.
This is especially useful during livestreams or screen shares, where the map source code itself may be visible, but the referenced file is not.
1. The Concept¶
Normally, the replacement field of a rule is the literal output text:
('my-secret-value', r'^(trigger)$', 85, {'command_flags': re.IGNORECASE})
With file-based replacement enabled, a replacement value that starts with a
configured prefix (by default - or .) is instead treated as a filename.
Aura resolves that filename relative to the plugin’s own directory, reads its
content, and uses that content as the replacement text.
('-api_key.txt', r'^(show api key)$', 85, {'command_flags': re.IGNORECASE})
If api_key.txt exists next to the plugin’s FUZZY_MAP_pre.py, its (stripped)
content is used as the replacement. If the file does not exist, the literal
string -api_key.txt is returned instead (fail-safe: no accidental leakage of
“file not found” as usable text, and no crash).
2. Settings¶
Configured in config/settings.py (or config/settings_local.py for local
overrides):
Setting |
Type |
Default |
Description |
|---|---|---|---|
|
|
|
Master switch for the whole feature. If |
|
|
|
|
|
|
|
If |
|
|
e.g. |
Resolved absolute paths starting with any of these are always rejected, regardless of |
3. Path Resolution¶
The file is resolved as follows:
The plugin’s
source_path(recorded automatically by the map loader) is joined againstSL5NET_AURA_PROJECT_ROOT(read from theSL5NET_AURA_PROJECT_ROOTenvironment variable) to get the plugin’s directory.The
replacementvalue is joined onto that directory.Unless
FILE4REPLACEMENT_ALLOW_PATH_TRAVERSALisTrue, the resolved path must stay inside the plugin’s directory, or the lookup is rejected.Regardless of the above, any resolved path starting with an entry in
FILE4REPLACEMENT_DENY_PREFIXESis always rejected.If the file exists, its stripped content is returned. Otherwise, the original
replacementstring is returned unchanged.
4. Security Notes¶
Only enable
FILE4REPLACEMENT_ALLOW_PATH_TRAVERSALif you understand the implications: it allows any user who can edit aFUZZY_MAP_prefile (e.g. via an online map editor) to read arbitrary files that the Aura process can access, and have their content surface as live output text.FILE4REPLACEMENT_DENY_PREFIXESprovides a baseline protection against common system directories even when path traversal is allowed, but it is not a substitute for restricting who can edit map files in the first place.Referenced files are plain text on disk. Combine with your OS’s file permissions if the content is sensitive.
5. Example¶
See config/maps/plugins/TEST_FILE4REPLACEMENT/ for a working example plugin,
and tools/tests/TEST_FILE4REPLACEMENT.sh for a test script that exercises
both an in-directory lookup and a lookup outside the plugin directory.
# config/maps/plugins/TEST_FILE4REPLACEMENT/de-DE/FUZZY_MAP_pre.py
FUZZY_MAP_pre = [
('.Zebra.txt', r'^(Zebra)$', 85, {'command_flags': re.IGNORECASE}),
]
Create .Zebra.txt next to this file with the desired replacement text, then
say (or type via the console) s Zebra to trigger it.