Profiles created via the Manager API have no way to pass custom Chromium command-line flags to the underlying browser. This blocks several common use cases:
- Loading Chrome extensions — Chrome Web Store explicitly blocks installation in non-Google-branded Chromium browsers ("Switch to Chrome to install"), so the only way to load an extension is via --load-extension=/path/to/extension. Filesystem-based workarounds (extracting CRX into Default/Extensions/
and patching Preferences) don't work because Chromium's tracked-preferences HMAC verification silently strips externally-added entries on launch.
- Disabling specific Chromium features — e.g. --disable-features=... for testing or stealth tuning.
- Custom origin/protocol allowlists — --unsafely-treat-insecure-origin-as-secure=... for development.
- Memory/process tuning — --js-flags=..., --single-process, etc.
Currently _build_fingerprint_args() constructs extra_args internally from fingerprint settings and passes them to launch_persistent_context_async(), but there's no hook to inject additional args from the profile config.
Proposed change
Add an optional launch_args: list[str] field to ProfileCreate / ProfileResponse and append it to extra_args before launch.
backend/models.py — add to ProfileCreate:
launch_args: list[str] = Field(default_factory=list)
backend/browser_manager.py — in the launch() method, before calling launch_persistent_context_async():
extra_args = self._build_fingerprint_args(profile, cdp_port)
extra_args += profile.get("launch_args", []) or []
That's the minimal change. Two lines plus a model field.
Example usage
curl -X POST http://localhost:8080/api/profiles \
-H "Content-Type: application/json" \
-d '{
"name": "with-ublock",
"fingerprint_seed": 12345,
"launch_args": ["--load-extension=/data/extensions/ublock-origin"]
}'
The user is responsible for ensuring extension paths exist inside the container (typically by mounting a volume into /data/extensions/ and pre-extracting unpacked extensions there).
Profiles created via the Manager API have no way to pass custom Chromium command-line flags to the underlying browser. This blocks several common use cases:
and patching Preferences) don't work because Chromium's tracked-preferences HMAC verification silently strips externally-added entries on launch.
Currently _build_fingerprint_args() constructs extra_args internally from fingerprint settings and passes them to launch_persistent_context_async(), but there's no hook to inject additional args from the profile config.
Proposed change
Add an optional launch_args: list[str] field to ProfileCreate / ProfileResponse and append it to extra_args before launch.
backend/models.py — add to ProfileCreate:
launch_args: list[str] = Field(default_factory=list)
backend/browser_manager.py — in the launch() method, before calling launch_persistent_context_async():
extra_args = self._build_fingerprint_args(profile, cdp_port)
extra_args += profile.get("launch_args", []) or []
That's the minimal change. Two lines plus a model field.
Example usage
curl -X POST http://localhost:8080/api/profiles \
-H "Content-Type: application/json" \
-d '{
"name": "with-ublock",
"fingerprint_seed": 12345,
"launch_args": ["--load-extension=/data/extensions/ublock-origin"]
}'
The user is responsible for ensuring extension paths exist inside the container (typically by mounting a volume into /data/extensions/ and pre-extracting unpacked extensions there).