Tunnel sources and subscriptions
tunnels[].source
- Type
object- Required
- Yes
- Default
- None
- Validation
- Its kind must be compatible with tunnel type and value must be non-empty.
- Secret classification
- Treat the whole object as sensitive until kind and value are inspected.
- Side effects
- Chooses where the agent or subscription refresher obtains provider input.
- Minimal example
source: { kind: config, value: secrets/edge.conf }
tunnels[].source.kind
- Type
enum- Required
- Yes
- Default
- None
- Validation
- Constants are config, subscription, xray-uri, and xray-json. Non-Xray tunnels require config; Xray accepts config or subscription. Inline xray-uri and xray-json are rejected by validation.
- Secret classification
- No by itself.
- Side effects
- Selects protected-file loading or fetch/prove/promote subscription flow.
- Minimal example
config
tunnels[].source.value
- Type
string- Required
- Yes
- Default
- None
- Validation
- Non-empty. For config, an absolute or config-directory-relative path; for subscription, an HTTPS fetch URL handled by the refresher.
- Secret classification
- Paths may reveal layout; subscription URLs and inline links are credentials.
- Side effects
- Reads a provider file or fetches a subscription; credential-bearing values are redacted from desired-state JSON.
- Minimal example
secrets/edge-wg.conf
- id: rotating-edge type: xray role: egress source: kind: subscription value: https://subscriptions.example.net/vless?token=SYNTHETIC-REPLACE-BEFORE-USEA refresh accepts at most 32 usable VLESS candidates and 8192 bytes per line, runs within a two-minute default deadline, rejects special-use/internal destinations, proves candidates in isolation, and promotes only a working one. The last-known-good link remains restorable.
The hub configuration loader does not decrypt an inline ENC[...] value. Put the real URL directly in root-owned /etc/vpn-hub/hub.yaml, keep the file and its parent directory inaccessible to other users, and never commit or paste it into diagnostics:
sudo chown root:root /etc/vpn-hub/hub.yamlsudo chmod 0700 /etc/vpn-hubsudo chmod 0600 /etc/vpn-hub/hub.yamlsudo stat -c '%U:%G %a' /etc/vpn-hub /etc/vpn-hub/hub.yamlExpected result: root:root 700 for the directory and root:root 600 for the file. Anyone who can read this file can use the subscription token. If it is disclosed, rotate the URL or token at the provider, update the file, run hubctl validate, deploy, verify a refresh, and only then revoke the old credential. SOPS protects provider files loaded by the agent; it is not a runtime secret source for fields in hub.yaml.
Next: Subscription lifecycle and Xray/VLESS.