Plugin repositories become rows an administrator manages, not one environment variable #93
Labels
No labels
accessibility
authentication
breaking change
bug
documentation
enhancement
interface
internationalisation
observability
security
tier
1
tier
2
tier
3
tier/4
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Blocks
Reference
Postulo/postulo#93
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Observation
This is the first of four. The others are the plugin kinds shown on the page, the policy
that lets an administrator decide a plugin for a person, and the page where a person sees
what is running for them.
What exists
Catalogues already work, and rather well.
plugins/catalogue.pyfetches a signed index,verifies Ed25519 against a configured public key, and refuses a wheel whose SHA-256 does not
match the one the signed index gave. Its docstring is worth keeping in view:
Several catalogues are already supported. What is missing is any way to manage them:
name|url|public-key, comma-separated, parsed withstr.split, empty by default. To addone you edit a file and restart the container. There is no row, no page, no switch, and no
notion that one catalogue might be more trusted than another.
What this asks for
A
PluginRepositoryrow per catalogue, with a tier:Internal is not a catalogue at all. It is the plugins that ship inside Postulo --
BUILTIN_SOURCEStoday -- shown as a repository so the page reads as one list rather thantwo unrelated ones. It has no URL and no key because nothing is fetched: the code is already
in the image, and it arrived the same way the rest of Postulo did. It cannot be disabled
because disabling it would mean disabling Postulo.
The environment still wins, using the mechanism that already exists.
site.ENV_OVERRIDESmaps a field to the variable that pins it and
site.overridden_by()says whether one is set;four settings already work this way and #84 extends it to SMTP. The official repository's URL
and key follow the same rule: pinned in the environment, they show their values, greyed out
and unwritable. Unpinned, they are editable. This should reuse that mechanism rather than
grow a second one -- and since it needs a list rather than a single row, extending
ENV_OVERRIDESto cover it is part of the work, not a detail.Four things to decide, and none of them is code
1. There is no official repository, and creating one is a commitment. Postulo does not
publish a catalogue. Doing so means generating a signing key, keeping it safe for the life of
the project, having a story for rotating it if it leaks, and deciding what "official" claims.
catalogue.pyalready answers the last part honestly and the page should keep saying it:A key that lives on one person's laptop and signs code that runs inside other people's
instances is a real responsibility. It should be taken deliberately or not at all -- and
until it is, the official row can ship disabled and empty rather than pointing nowhere.
2. Changing a repository's public key is a security event, not an edit. The key is the
only thing standing between an index and arbitrary code. Editing it in a form beside the URL
makes it look like a preference. It needs a confirmation that says what is being given up,
and the change belongs in an audit trail.
3. What happens to plugins already installed from a repository that is switched off.
They keep working -- they are installed, the code is on the volume, and silently disabling
somebody's working notifier because a URL was toggled would be its own bug. What stops is
updating and installing from it. The page has to say that, or an administrator will assume
"off" means "gone".
4. Whether a custom repository may be added at all on an instance somebody else operates.
It is the point where an operator can introduce code into an application holding other
people's CVs. That is legitimate -- it is their server -- but it deserves the same plainness
the install page already uses.
Scope
PluginRepositorymodel with the tier, enabled flag, URL and key; the internal rowsynthesised rather than stored.
catalogue.configured()reads rows and merges the environment over them, keeping itscurrent shape so nothing downstream changes.
remove a custom one; the official one editable only when the environment leaves it alone;
the internal one shown and unswitchable.
POSTULO_PLUGIN_CATALOGUEScurrently holds, so anexisting instance loses nothing.
tests/security/for the refusals: no key, no repository; a disabled repository servesnothing; an environment-pinned field cannot be written through the form.
Classification
Enhancement, interface. Not breaking: the environment variable keeps working and keeps
winning.