======================= Repository access views ======================= As part of adding :ref:`repository hosting ` to Debusine, it needs to be able to serve repositories from :ref:`debian:archive ` collections in an `apt-compatible format `__. Domains ======= Since Debusine's ``Set-Cookie`` header doesn't include a ``Domain`` attribute, its cookies are not available to subdomains. It should therefore be safe to run repositories from a subdomain of ``DEBUSINE_FQDN``: content served from that subdomain will not be able to run session fixation attacks on its parent domain. A reasonable default would be ``deb.{DEBUSINE_FQDN}``: shorter than ``repositories``, not protocol-specific like ``ftp``, and familiar from ``deb.debian.org``. However, we can include a setting such as ``DEBUSINE_DEBIAN_ARCHIVE_FQDN`` to allow instances to override this. Repositories will normally be served over HTTPS, but public repositories may also be served over HTTP. This is sometimes useful for bootstrapping minimal environments that lack certificates. URL paths ========= The basic path to a repository is ``/{scope}/{workspace}``, relying on the fact that archive collections are :ref:`singletons `. Suites in the archive are mapped onto subdirectories of ``dists/`` as usual. .. todo:: In future, we might also provide the ability to map particular repositories onto different URLs. `by-hash `__ paths are handled specially: they are translated into a search for a repository index in the correct suite with the correct path and checksum. That repository index need not be the active index for its path in the suite; it can be served as long as the suite's ``full_history_retention_period`` has not expired. ``/{scope}/{workspace}/{timestamp}``, where ``timestamp`` has the format ``YYYYMMDDTHHMMSSZ``, e.g. ``20250529T133100Z`` for 13:31 UTC on 29 May 2025, addresses the state of the repository as it existed at ``timestamp``. This is done by looking up collection items that have ``created_at`` and ``removed_at`` fields bracketing the given timestamp, rather than just those that are active (with ``removed_at`` unset), and can be done as long as the suite's ``full_history_retention_period`` has not expired. This URL format is compatible with snapshot.debian.org and snapshot.ubuntu.com; like those services, a user can request any timestamp as a snapshot ID, and the server will provide the indexes and other files that were current at that point in time. .. todo:: Add a `Snapshots `__ field to generated ``Release`` files, pointing to the corresponding URL format. .. todo:: Once we've defined how `repository signing `__ works, we should also publish each repository's public keys in some standard location. Authentication and authorization ================================ APT only handles HTTP Basic Authentication, so we're stuck with that mechanism, but we can still use our existing user tokens: users may use their user name with their user token acting as a password. Downloading files from a repository requires the "viewer" role on the workspace. Cache control ============= Responses to different URLs in a repository should be cached in different ways, and Debusine sends the ``Cache-Control`` response header to inform HTTP caches of this. ``by-hash`` files under ``dists/``, and all files resulting from a timestamp-specific query are immutable: they may be removed, but they won't be replaced with different contents at the same URL. This is also true for files under ``pool/`` in archives where ``may_reuse_versions`` is false. For these files, Debusine sends ``Cache-Control: max-age=31536000`` (i.e. 365 days, an arbitrary long period). For other files, Debusine sends ``Cache-Control: max-age=1800, proxy-revalidate`` to indicate that shared caches should revalidate responses before reuse if they are older than half an hour. (This period is also arbitrary, but should be a good starting point.) Debusine also sends ``Vary: Authorization`` for all responses to repository URLs, since its responses depend on whether the requester has the "viewer" role on the workspace. Examples ======== If we were to create an archive collection in ``debian/base`` on debusine.debian.net and generate indexes for its suites, then APT configuration for it might look something like this:: Types: deb deb-src URIs: https://deb.debusine.debian.net/debian/base Suites: bookworm Components: main contrib non-free non-free-firmware A snapshot of it from the start of May 2025 might be as follows (in this case we have to add the snapshot ID to the URL, as we don't control the ``Release`` file and can't add a ``Snapshots`` field to it):: Types: deb deb-src URIs: https://deb.debusine.debian.net/debian/base/20250501T000000Z Suites: bookworm Components: main contrib non-free non-free-firmware An experiment workspace based on ``debian/developers`` might look like this:: Types: deb deb-src URIs: https://deb.debusine.debian.net/debian/developers-test Suites: sid Components: main Or a snapshot, once Debusine's generated ``Release`` files gain a ``Snapshots`` field:: Types: deb deb-src URIs: https://deb.debusine.debian.net/debian/developers-test Snapshot: 20250501T000000Z Suites: sid Components: main