Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 22, 2026

Add a digital_asset_links_sites configuration option that generates a DAL JSON file for HTTPS origins and serves it safely from the add-on, with Cloudflare tunnel routing guidance.

  • Configuration + validation
    • Added digital_asset_links_sites to config schema and English translation with strict HTTPS origin validation, de-duplication, and stable ordering.
  • DAL file generation
    • Generate ${DAL_ROOT}/www/.well-known/assetlinks.json and BusyBox httpd.conf with application/json MIME mapping under /data/digital-asset-links.
  • Serving + routing
    • Start BusyBox httpd on 127.0.0.1:36555 and insert a /.well-known/* ingress rule for locally managed tunnels; documented remote-managed routing expectations.
  • Quality gates
    • Removed non-English translations to keep English-only support.
    • Added pytest unit tests for config schema, translation coverage, and DAL bash logic validation using a pinned bashio git checkout.
    • Introduced a uv-managed pyproject.toml with pinned pytest and uv.lock, and updated CI to use setup-uv with uv sync/uv run plus a pinned Python version.
    • Updated GitHub Actions pins to follow the actions/docker-only version pinning policy and smoke-test the locally built image by ID.

Example config:

digital_asset_links_sites:
  - https://ha.example.com
  - https://vault.example.com:8443
Original prompt

Shared: Digital Asset Links support

Project: https://github.com/BTreeMap/hass-tailscale
Project: https://github.com/BTreeMap/hass-cloudflared

(Note that you only need to work on the current project; but this documentation is shared to ensure both agents align their work)

New configuration option

Add to both add-ons:

  • digital_asset_links_sites (list of strings; default empty)

Meaning: when non-empty, the add-on generates a Digital Asset Links JSON file that lets Chrome/Google Password Manager share saved credentials across the listed HTTPS origins.

Validation requirements:

  • Each entry MUST be an https:// origin; domain[:optional_port] is allowed (Chrome documents an optional port).
  • De-duplicate entries and write stable output ordering.

Files written (inside container, no mounts)

Use an add-on-owned base directory, e.g.:

  • DAL_ROOT=/var/lib/hass-digital-asset-links (or /data/digital-asset-links if you prefer to keep it in the add-on’s persistent data area)

Generate:

  • ${DAL_ROOT}/www/.well-known/assetlinks.json

Keep ${DAL_ROOT}/www containing only .well-known/ so there’s nothing else to fetch if a client probes random URLs. github

Generated JSON format

Write an array of entries like:

  • relation: ["delegate_permission/common.get_login_creds"]
  • target: { "namespace": "web", "site": "<origin>" }

Content-Type requirements

Chrome requires the DAL response be JSON with Content-Type: application/json, and the file must be hosted at /.well-known/assetlinks.json on each domain you want affiliated.

hass-tailscale: serve DAL via tailscale serve (no BusyBox)

Rationale

Avoid starting any extra HTTP listener inside the add-on because it reuses the system network stack (port conflict risk).
Instead, mount the generated file directly with Tailscale Serve.

Behavior

When share_homeassistant: true:

  • Existing: serve/proxy Home Assistant at /.
  • New (if digital_asset_links_sites is non-empty): also serve the generated file at /.well-known/assetlinks.json via tailscale serve.

Implementation notes:

  • tailscale serve supports mounting targets at URL paths with --set-path, and mount matching follows “most specific path wins” behavior (Go ServeMux style). github
  • Ensure the file target you pass is an absolute path (the generated path under ${DAL_ROOT}). (Keep this as a documented requirement in code/comments.)

Illustrative commands:

# 1) Proxy HA at /
tailscale serve --bg --https=${share_on_port} --set-path=/ 8123

# 2) Serve DAL file at exact well-known path
tailscale serve --bg --https=${share_on_port} --set-path=/.well-known/assetlinks.json \
  ${DAL_ROOT}/www/.well-known/assetlinks.json

(Keep your existing share_on_port constraints unchanged.)

hass-cloudflared: serve DAL via BusyBox httpd on high port

Rationale

Cloudflare Tunnel needs an origin to answer /.well-known/assetlinks.json. For the add-on, the minimal/safe approach is a local static server that serves only that file (and nothing else), bound to loopback on a high unprivileged port.

BusyBox httpd specifics (must implement exactly)

Pick a port in the 30000–40000 range; use:

  • DAL_HTTP_PORT=36555

Write BusyBox config file:

  • ${DAL_ROOT}/httpd.conf containing:
H:${DAL_ROOT}/www
.json:application/json

BusyBox httpd supports -p [IP:]PORT, -h HOME, config with -c FILE, and H: sets the server root (overrides -h). github
BusyBox httpd supports MIME mappings by extension in its config (so .json:application/json ensures correct Content-Type). github

Start server (only if digital_asset_links_sites is non-empty):

busybox httpd -f -p 127.0.0.1:36555 -h ${DAL_ROOT}/www -c ${DAL_ROOT}/httpd.conf

Binding to 127.0.0.1 prevents accidental LAN exposure; the tunnel process can still reach it locally. github

Cloudflare tunnel routing documentation

  • If the tunnel is locally managed (no token): the add-on should configure an ingress rule to send /.well-known/* to http://127.0.0.1:36555, then fall through to the existing HA service for other paths.
  • If the tunnel is remotely managed (token-based): document that the user must add an equivalent path-based rule in Cloudflare’s dashboard because the routing is controlled there.

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 3 commits January 22, 2026 05:47
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copilot AI changed the title [WIP] Add configuration option for digital asset links Add Digital Asset Links support to Cloudflared add-on Jan 22, 2026
Copilot AI requested a review from MinecraftFuns January 22, 2026 05:52
@MinecraftFuns
Copy link
Contributor

@copilot i want to drop support for all languages other than English; i also want you to add unit tests to all configuration options with comprehensive test cases, and integration tests run via github actions to test that the containers should start without any issue under correct configuration. follow best practices to ensure quality control/gate

Copilot AI and others added 4 commits January 22, 2026 06:19
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 22, 2026

@copilot i want to drop support for all languages other than English; i also want you to add unit tests to all configuration options with comprehensive test cases, and integration tests run via github...

Completed the requested updates: non-English translations removed, pytest-based config/translation coverage added, and CI now runs tests plus a tagged smoke-test container start. Commit: e9f906f.

@MinecraftFuns
Copy link
Contributor

@copilot it's fine to use pytest for testing but the main goal is that these bash functions and logics perform what they intend to do and are bug-free across a comprehensive set of inputs. while YAML formatting quality check is already covered by the linter

Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 22, 2026

@copilot it's fine to use pytest for testing but the main goal is that these bash functions and logics perform what they intend to do and are bug-free across a comprehensive set of inputs. while YAML ...

Added bash-focused DAL validation tests that exercise the script logic across scheme/path/port/dedupe cases and updated the runner to allow isolated execution. Commit: 7e763a6.

@MinecraftFuns
Copy link
Contributor

@copilot 1. please address this issue; we only have GHCR access and even so you should not add an additional image tag for the purpose of running your smoke test; the existing tags should be enough, or you could pull the image from the local dockerd;

logs:

Run IMAGE_TAG="hass-cloudflared-smoke:aadcf2007aaa7e9056cc8a24d10770031030f17c-amd64"
Unable to find image 'hass-cloudflared-smoke:aadcf2007aaa7e9056cc8a24d10770031030f17c-amd64' locally
docker: Error response from daemon: pull access denied for hass-cloudflared-smoke, repository does not exist or may require 'docker login': denied: requested access to the resource is denied

Run 'docker run --help' for more information
Error: Process completed with exit code 125.
2. for the tests, they could be more properly set up with uv managing dependencies and actions/setup-python to pin down the python version. follow best practices on modern python dev and use latest dependencies. for github actions under the actions/ username you should pin the version number only and allow the underlying commit hash to drift since they are considered trustworthy
3. the bashio and other libraries referenced in the scripts and needed for tests can be found at https://github.com/hassio-addons/bashio and you can load them directly during test, instead of mocking them or storing a copy of them in the current repository

Copilot AI and others added 5 commits January 22, 2026 22:08
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copilot AI and others added 3 commits January 22, 2026 22:15
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 22, 2026

@copilot 1. please address this issue; we only have GHCR access and even so you should not add an additional image tag for the purpose of running your smoke test; the existing tags should be enough, o...

Updated CI to use local image IDs (no extra tags), switched pytest setup to uv + pinned Python, and replaced mocks with pinned bashio download + checksum/SSL/path checks. Commit: 8c1d5b1.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/hassio-addons/bashio/commits/main
    • Triggering command: /usr/bin/curl curl -s REDACTED (http block)
  • https://api.github.com/repos/hassio-addons/bashio/contents/lib
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@MinecraftFuns
Copy link
Contributor

@copilot to clarify, only actions from actions/ and docker/ are trustworthy and don't need to have their commit hash pinned; other actions are not exempted. also when i say "using uv" i mean a modern uv-managed python project with pyproject.toml properly set up for testing, not to use uv in the runtime to install pip libraries; uv should still be the only manager of the python venv, but it's not used like that. follow best practices.

Copilot AI and others added 2 commits January 22, 2026 22:42
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 22, 2026

@copilot to clarify, only actions from actions/ and docker/ are trustworthy and don't need to have their commit hash pinned; other actions are not exempted. also when i say "using uv" i mean a modern ...

Adjusted action pinning per policy, introduced a uv-managed pyproject with pytest pinned, and updated CI to use uv sync/run. Commit: 528977a.

@MinecraftFuns
Copy link
Contributor

@copilot please address issues with wrong uv usage patterns. in the CI file, please use the setup-uv actions

test-pytest:
name: Pytest
runs-on: ubuntu-latest
steps:
- name: ⤵️ Check out code from GitHub
uses: actions/checkout@v6
- name: 🐍 Set up Python
uses: actions/setup-python@v6.2.0
with:
python-version: "3.12"
- name: ⚡ Set up uv
uses: astral-sh/setup-uv@v7.2.0
with:
version: "0.9.26"
- name: 🧰 Install test dependencies
run: uv sync --no-dev
- name: ✅ Run pytest
run: uv run pytest

the uv.lock file is missing and is required for the uv command to work.

the bashio should be loaded via git clone, not an HTTP request to the code load endpoint.

def run_share(tmp_path, config_path, *, status_json=None, extra_env=None):
env = os.environ.copy()
bashio_dir = tmp_path / "bashio"
if not bashio_dir.exists():
subprocess.run(
["git", "clone", "--depth", "1", "https://github.com/hassio-addons/bashio", str(bashio_dir)],
check=True,
capture_output=True,
text=True,
)
data_root = tmp_path / "data"
env.update(
{
"PATH": f"{FIXTURES}:{env['PATH']}",
"BASH_ENV": str(FIXTURES / "bashio_env.sh"),
"BASHIO_DIR": str(bashio_dir),
"BASHIO_CONFIG_JSON": str(config_path),
"TAILSCALE_BIN": str(FIXTURES / "tailscale_stub.sh"),
"TAILSCALE_LOG": str(tmp_path / "tailscale.log"),
"DATA_DIR": str(data_root),
}
)
if status_json is not None:
env["TAILSCALE_STATUS_JSON"] = status_json
if extra_env:
env.update(extra_env)
result = subprocess.run(
["bash", str(RUN_SCRIPT)],
env=env,
cwd=str(REPO_ROOT),
capture_output=True,
text=True,
)
return result, data_root

please address the above issues following best practices

Copilot AI and others added 2 commits January 22, 2026 23:52
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Co-authored-by: MinecraftFuns <25814618+MinecraftFuns@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Jan 22, 2026

@copilot please address issues with wrong uv usage patterns. in the CI file, please use the setup-uv actions

test-pytest:
...

Switched CI to setup-uv with pinned version, added uv.lock, and updated tests to clone bashio via git with pinned checkout plus error reporting. Commit: b7e8335.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • https://api.github.com/repos/astral-sh/setup-uv/releases/tags/v7.2.0
    • Triggering command: /home/REDACTED/work/_temp/ghcca-node/node/bin/node /home/REDACTED/work/_temp/ghcca-node/node/bin/node --enable-source-maps /home/REDACTED/work/_temp/copilot-developer-action-main/dist/index.js (http block)

If you need me to access, download, or install something from one of these locations, you can either:

@MinecraftFuns MinecraftFuns marked this pull request as ready for review January 23, 2026 00:20
@MinecraftFuns MinecraftFuns merged commit d0c7ed4 into main Jan 23, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants