kych

OAuth 2.0 API for Swiyu to enable Taler integration of Swiyu for KYC (experimental)
Log | Files | Refs | Submodules | README | LICENSE

README.source (9887B)


      1 Building the kych package
      2 =========================
      3 
      4 This source package produces two binary packages: **kych**, the OAuth 2.0
      5 gateway built from the Rust crate in this tree, and **swiyu-verifier**, the
      6 SWIYU Generic Verifier built from the pinned upstream checkout in
      7 swiyu-verifier/upstream.
      8 
      9 Binary-only builds from a git checkout, which is how the packages are
     10 produced:
     11 
     12     git submodule update --init
     13     ./debian/stamp-version.sh
     14     dpkg-buildpackage -b -uc -us
     15 
     16 The submodule step is not optional: without it debian/rules stops with
     17 "swiyu-verifier/upstream is empty".  "make deb" at the top of the tree runs
     18 the last two steps for you.
     19 
     20 A tarball from "make dist" can be built the same way, and needs no .git to do
     21 it: the tarball carries the submodule and a .version file, which is what
     22 stamp-version.sh reads when git is not available.
     23 
     24 The second step rewrites debian/changelog with the version reported by
     25 scripts/get_version.sh -- the same "git describe --tags" logic the other GNU
     26 Taler repositories use -- because dpkg takes the package version from the
     27 changelog and from nowhere else.  It is idempotent, and it falls back to
     28 0.0.0-<commits>-g<hash> while this repository still has no release tag.  Note
     29 that it needs the .git directory; building from an exported tree means
     30 stamping the changelog before exporting.
     31 
     32 Build dependencies beyond the usual: cargo and rustc for the gateway,
     33 python3-sphinx for the man pages, and maven plus openjdk-25-jdk-headless for
     34 the verifier.
     35 
     36 A build takes a few minutes, most of it Maven fetching some 300 MB into
     37 debian/m2 -- which "clean" removes again, so every build re-downloads it.
     38 While working on the packaging, point it at a cache of your own instead, and
     39 it is left alone:
     40 
     41     MAVEN_REPO=$HOME/.m2/repository dpkg-buildpackage -b -uc -us
     42 
     43 Notes for whoever touches this next
     44 -----------------------------------
     45 
     46 * No debian/source/format is present, so the source format is the default 1.0.
     47   This matches the other Rust packages in the GNU Taler tree (robocop,
     48   taler-rust) and is fine for the "-b" builds above; producing a source package
     49   would need a format decision and an orig tarball first -- and, with the
     50   submodule, a decision about how the verifier's source travels in it.
     51 
     52 * The crate has one path dependency, ../taler-config, which is the vendored
     53   copy of the GNU Taler configuration parser, logging setup and socket-binding
     54   logic; see taler-config/README for what it is and how to re-sync it.  Cargo
     55   builds it as part of the main crate, so it needs no separate step -- but
     56   "debian/rules clean" has to remove its target/ as well.
     57 
     58 * The build is not offline: cargo fetches crates from crates.io into
     59   debian/cargo (CARGO_HOME) and Maven fetches from Maven Central into
     60   debian/m2, so that nothing outside the build tree is written.  There is a
     61   Cargo.lock for the gateway, so its dependency versions are pinned; the
     62   verifier's are pinned by upstream's pom.  Both would still have to be
     63   vendored before this could go to the Debian archive; neither matters for the
     64   .deb builds we do.
     65 
     66 * The verifier build passes -Dpgpverify.skip=true.  Upstream binds the
     67   pgpverify plugin to the "validate" phase, where it checks the PGP signature
     68   of every dependency against pgp/keys.list by querying public keyservers.
     69   That is a worthwhile check in upstream's CI, with a warm key cache; in a
     70   package build it makes the build depend on keys.openpgp.org being reachable,
     71   and it is upstream's own documented escape hatch.  Reconsider if the build
     72   ever moves somewhere that can cache those keys.
     73 
     74 * -DskipTests as well: the verifier's tests need Testcontainers and therefore a
     75   container runtime.
     76 
     77 * debian/rules names the JDK explicitly
     78   (JAVA_HOME=/usr/lib/jvm/java-25-openjdk-$(DEB_HOST_ARCH)).  The verifier
     79   moved to Java 25 in its 5.0.0 release, so a host whose default JDK is older
     80   -- which is most hosts -- would otherwise fail the build with a
     81   release-version error.  Trixie has openjdk-25; bookworm does not, and
     82   building there means pinning the submodule back to a 4.x tag, which also
     83   reverts to Java 21.
     84 
     85 * The jar the swiyu-verifier package installs is a Spring Boot "fat" jar of
     86   about 140 MB: it embeds every Java dependency of the verifier.  That is why
     87   the package is large, and why debian/copyright carries an INCOMPLETE note --
     88   those dependencies' licenses are not enumerated.  Upstream's
     89   THIRD-PARTY-NOTICES.md and the sbom.json published with each release are the
     90   starting point.
     91 
     92 * Man pages are generated at build time by sphinx-build from
     93   documentation/taler-docs/manpages/, the same reStructuredText that the
     94   taler-docs repository renders for the website, so there is one source for
     95   both.  The configuration used here is documentation/sphinx-man/conf.py, a
     96   minimal file holding little more than the man_pages entries; taler-docs has
     97   its own conf.py with a long list of extensions, which is why we do not reuse
     98   it.  The NAME line of each page comes from the man_pages entry, not from the
     99   document, which is why each source wraps its own "Name" section in
    100   ".. only:: html".
    101 
    102   Consequences worth knowing: the man page sources may only use directives that
    103   plain Sphinx understands (they currently use "only", "code-block", "note" and
    104   "warning"), and the build prints "document isn't included in any toctree" for
    105   every page but the root document.  Those warnings are expected here - the
    106   toctree lives in taler-docs - and cannot be suppressed, as they carry no
    107   warning type.
    108 
    109 * The daemon serves its QR-code JavaScript from a path relative to the process
    110   working directory, so debian/kych.service sets WorkingDirectory to
    111   /usr/share/kych, where debian/kych.install puts js/.  Changing either without
    112   the other breaks the /authorize page.
    113 
    114 Things that are easy to get wrong
    115 ---------------------------------
    116 
    117 Each of these was wrong at some point and cost a debugging session:
    118 
    119 * debian/*.sysusers: the third column is the numeric ID, *not* the GECOS
    120   field.  With the description in that position systemd-sysusers fails the
    121   installation with "Failed to parse UID".
    122 
    123 * debian/kych.service needs SupplementaryGroups=kych.  Group=www-data replaces
    124   the primary group -- which is what gives the listening socket a group the
    125   reverse proxy can use -- and systemd then does not add the groups the kych
    126   user is a member of.  Without the line the daemon cannot read its own
    127   root:kych 0640 configuration.
    128 
    129 * dh_installsystemd must not be passed --no-stop-on-upgrade.  Despite the name
    130   it also turns off the restart after an upgrade (see dh_installsystemd(1)),
    131   which leaves the old binary running.  --no-enable alone is what gives "do not
    132   start on first install, but restart if running".
    133 
    134 * The verifier's signing key cannot live in swiyu-verifier.env: a systemd
    135   EnvironmentFile cannot express the newlines of a PEM document, and an escaped
    136   "\n" reaches the JVM as two characters, which fails with "No PEM key found".
    137   It goes into /etc/swiyu-verifier/secrets/signing-key.yml, which the shipped
    138   application.yml imports with spring.config.import.
    139 
    140 Upstreaming the man pages
    141 -------------------------
    142 
    143 documentation/taler-docs/manpages/ is copied into the taler-docs checkout as
    144 described in documentation/taler-docs/README.  Sphinx there will not build a
    145 man page unless it is also listed in taler-docs/conf.py, so the entries from
    146 documentation/sphinx-man/conf.py have to be added to the man_pages list there
    147 as well, with a "manpages/" prefix on the first field:
    148 
    149     ("manpages/kych-oauth2-gateway.1", "kych-oauth2-gateway",
    150      "OAuth 2.0 gateway for SWIYU credential verification",
    151      ["GNU Taler contributors"], 1),
    152     ("manpages/kych-client-management.1", "kych-client-management",
    153      "manage OAuth 2.0 clients of the KyCH gateway",
    154      ["GNU Taler contributors"], 1),
    155     ("manpages/kych-dbinit.1", "kych-dbinit",
    156      "initialise and upgrade the KyCH database schema",
    157      ["GNU Taler contributors"], 1),
    158     ("manpages/kych-dbconfig.1", "kych-dbconfig",
    159      "create the PostgreSQL database for KyCH",
    160      ["GNU Taler contributors"], 1),
    161     ("manpages/swiyu-verifier.1", "swiyu-verifier",
    162      "SWIYU Generic Verifier service",
    163      ["GNU Taler contributors"], 1),
    164     ("manpages/swiyu-verifier-dbconfig.1", "swiyu-verifier-dbconfig",
    165      "create the PostgreSQL database for the SWIYU verifier",
    166      ["GNU Taler contributors"], 1),
    167     ("manpages/kych.conf.5", "kych.conf",
    168      "configuration file of the KyCH OAuth 2.0 gateway",
    169      ["GNU Taler contributors"], 5),
    170 
    171 Keep the two lists identical, or the same source will produce a different NAME
    172 line depending on who builds it.
    173 
    174 taler-docs also carries shared fragments that kych.conf.5.rst now duplicates in
    175 its own words: frags/common-conf-syntax.rst for the file format and
    176 manpages/frags/common-serve-options.rst for SERVE/BIND_TO/PORT/UNIXPATH, both
    177 pulled in with ".. include::" by the sibling components.  Switching to them
    178 would be the right move once the page lives in taler-docs -- but it cannot
    179 happen here, because the fragments are not in this repository and the Debian
    180 build renders these sources standalone.
    181 
    182 Updating the verifier
    183 ---------------------
    184 
    185 The verifier is a git submodule pinned to a release tag, not a branch:
    186 
    187     cd swiyu-verifier/upstream
    188     git fetch --tags
    189     git checkout <new tag>
    190     cd ../..
    191     git add swiyu-verifier/upstream
    192 
    193 Read upstream's CHANGELOG.md and migration-guides/ before doing so.  Its
    194 releases have broken things that this packaging and the gateway depend on more
    195 than once: 3.0.0 dropped DIF Presentation Exchange in favour of DCQL (which is
    196 why src/handlers.rs builds a dcql_query), 4.0.0 removed client_id_scheme in
    197 favour of client_id_prefix, and 5.0.0 moved the build to Java 25 and the
    198 disclosed claims into a new dcql_response field.
    199 
    200  -- Taler Systems SA <deb@taler.net>