Skip to content

Expose custom Chromium launch args on profile API (e.g. for --load-extension) #10

@serxasz

Description

@serxasz

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).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions