1. Overview
BastionGuard-secure is the Secure Payments entry point responsible for launching the CEF sandboxed browser flow when (and only when) the requested URL matches a domain allowlist. The program also implements two critical runtime controls:
- Graphics backend selection (Wayland vs X11) to improve compatibility and stability with GTK/CEF.
- Deterministic DNS bypass via bubblewrap (
bwrap) by overriding/etc/resolv.confinside a mount namespace (no network namespace required).
The entry point integrates with the SecureList policy layer (domain allowlist) and the SecureBrowser launcher to decide whether to use the sandboxed CEF UI or fall back to the system browser.
2. Responsibilities
- Handle CEF subprocess execution (
CefExecuteProcess). - Optionally re-exec itself inside a bwrap container with custom DNS resolvers.
- Detect and configure the display backend (
GDK_BACKEND,OZONE_PLATFORM). - Enforce Secure Payments policy by calling
SecureList::open_if_allowed().
3. Components and Dependencies
- CEF (Chromium Embedded Framework) – process model and sandboxed browser execution:
CefMainArgsCefExecuteProcess
- SecureList – domain allowlist enforcement (payments.json “list” key).
- SecureBrowser – CEF UI launcher used when the allowlist policy matches.
- Bubblewrap (bwrap) – mount namespace isolation for deterministic DNS resolution.
- glib/gettext – i18n via
bindtextdomain,textdomain, and_().
4. CEF Process Model Handling
CEF uses a multi-process architecture (renderer, GPU, utility). The entry point correctly delegates these subprocess invocations to CEF and exits early when needed:
- Create
CefMainArgsfromargc/argv. - Call
CefExecuteProcess(). - If the return code is
>= 0, the current process is a CEF subprocess and must exit immediately.
This ensures the main process does not incorrectly continue initialization logic in renderer/GPU contexts.
5. Graphics Backend Selection (Wayland/X11)
5.1 Detection
The runtime selects a preferred backend using environment inspection:
- If
WAYLAND_DISPLAYis set → Wayland session detected. - Else if
DISPLAYis set → X11 session detected. - Else → fallback to X11.
5.2 Applied Environment Variables
According to the detected session, the program sets:
GDK_BACKEND=waylandorx11OZONE_PLATFORM=waylandorx11
This helps align GTK/CEF behavior with the actual compositor/display server and reduces ambiguous backend selection issues.
5.3 Optional Software Rendering
An optional stability mode is implemented via an environment flag:
- If
BASTIONGUARD_FORCE_SOFTWARE_GL=1→ setLIBGL_ALWAYS_SOFTWARE=1.
This may be used to mitigate GPU driver instability at the cost of performance.
6. Deterministic DNS Bypass (Bubblewrap)
6.1 Goal
The application optionally re-execs itself in a restricted environment to override DNS resolution deterministically (e.g., to avoid reliance on local resolvers such as dnsmasq). This is implemented by mounting a custom /etc/resolv.conf inside a bubblewrap container.
6.2 DNS Configuration
A temporary resolver file is created:
/tmp/bastionguard-resolv.conf
It contains public resolver entries and conservative options:
- Cloudflare:
1.1.1.1 - Quad9:
9.9.9.9 - Google:
8.8.8.8 options timeout:2 attempts:3 rotate
6.3 Re-exec Conditions
The re-exec is performed only if all conditions are satisfied:
- The process is not already inside bubblewrap (checked via
BASTIONGUARD_IN_BWRAP). bwrapis available on the system (command -v bwrapsucceeds).- The bypass is not disabled via
BASTIONGUARD_NO_BWRAP=1.
6.4 Bubblewrap Isolation Model
The bubblewrap invocation creates an isolated mount environment with the following properties:
- Read-only root filesystem:
--ro-bind / / - Functional /dev and /proc:
--dev /dev,--proc /proc - Writable /tmp:
--tmpfs /tmp - DNS override: bind-mount the generated file over
/etc/resolv.conf - Writable CEF cache path: bind-mount a host-writable cache directory to itself
- XDG_RUNTIME_DIR passthrough (if present): bind-mount for Wayland/session resources
- Lifecycle control:
--die-with-parentand--new-session
The design explicitly avoids creating a separate network namespace (unshare-net is not used), therefore it typically does not require elevated privileges and uses the host’s existing network stack while still controlling DNS resolution within the process namespace.
6.5 Recursion Prevention
To avoid infinite re-exec loops, the program sets:
BASTIONGUARD_IN_BWRAP=1
in the bubblewrap environment.
7. Secure Payments Policy Enforcement
7.1 CLI Contract
The executable expects at least one argument:
BastionGuard-secure <url>
If no URL is provided, it prints usage guidance and exits with status 2.
7.2 Decision Flow
After environment preparation and parameter validation, the program delegates the routing decision to:
SecureList::open_if_allowed(url, argc, argv);
Policy behavior (implemented by SecureList):
- If Secure Payments is enabled in SettingsStore and the domain matches
~/.config/BastionGuard/payments.json(list), the URL is opened inside SecureBrowser (CEF sandbox). - Otherwise, the URL is opened in the system browser.
8. Runtime Flags
- BASTIONGUARD_NO_BWRAP=1 – disables the bubblewrap DNS bypass entirely.
- BASTIONGUARD_IN_BWRAP=1 – internal recursion guard set only inside the bwrap execution context.
- BASTIONGUARD_FORCE_SOFTWARE_GL=1 – forces software rendering by setting
LIBGL_ALWAYS_SOFTWARE=1.
9. Operational and Security Considerations
- DNS determinism: overriding
/etc/resolv.confinside a mount namespace ensures predictable DNS servers for the secure browsing context, independent of host resolver configuration. - Isolation scope: the bubblewrap usage primarily hardens filesystem and resolver behavior; it does not isolate networking since no network namespace is created.
- Writable surfaces: only the CEF cache path and
/tmpare made writable; the rest of the filesystem remains read-only, reducing persistence risk. - UI backend stability: explicit Wayland/X11 selection and optional software rendering reduce CEF/GTK compatibility issues across heterogeneous desktop environments.
- Policy centralization: the actual “allowed vs not allowed” decision is delegated to SecureList, keeping this entry point focused on environment preparation and process lifecycle correctness.
10. Typical Execution Sequence
- Process starts and initializes gettext locale domain.
- CEF subprocess check runs; subprocesses exit early.
- If enabled and available, the process re-execs inside bubblewrap with DNS override.
- URL argument is validated.
- Wayland/X11 backend is configured.
- SecureList enforces allowlist policy and launches SecureBrowser or the system browser.