fix: harden fips startup and app port relays
This commit is contained in:
@@ -45,12 +45,44 @@ Completed locally in this pass:
|
||||
schema can be audited without a Python `PyYAML` dependency.
|
||||
- Updated root/community docs, CI, PR template, app developer notes, and
|
||||
container/deployment docs toward public contributor expectations.
|
||||
- Fixed native FIPS activation fallback: nodes that have the packaged
|
||||
`fips.service` but not `archipelago-fips.service` now start the available
|
||||
unit instead of repeatedly failing activation against a missing unit. The UI
|
||||
now labels the action as `Start` instead of making native FIPS look like an
|
||||
installable app.
|
||||
- Fixed the FIPS app-port relay design so it binds relays to the node's FIPS
|
||||
ULA instead of wildcard `[::]`, avoiding collisions with Podman-published app
|
||||
ports such as FileBrowser `8083` and Botfights `9100`.
|
||||
- Added `docs/nostr-git-source-hosting.md`, a NIP-34/ngit/GRASP source hosting
|
||||
plan using a Bitcoin Core-style maintainer model: public review and easy
|
||||
forks, with canonical merge rights held by a small signed maintainer set.
|
||||
|
||||
Verified locally:
|
||||
|
||||
- `./scripts/audit-secrets.sh` passes.
|
||||
- Full `apps/*/manifest.yml` repository audit passes with warnings only.
|
||||
- `bash -n` passes for the edited shell scripts.
|
||||
- Targeted FIPS dashboard vitest passes.
|
||||
- Targeted Rust tests for FIPS service unit detection and FIPS app relay
|
||||
address selection pass.
|
||||
|
||||
Verified on a Linux Archipelago verification node:
|
||||
|
||||
- Native FIPS was restored by starting the already-installed packaged
|
||||
`fips.service`; the daemon became active and joined the FIPS tree.
|
||||
- Correct local lifecycle API endpoint is HTTP, not HTTPS
|
||||
(`ARCHY_HOST=127.0.0.1 ARCHY_SCHEME=http`).
|
||||
- Read-only lifecycle run progressed past login and confirmed required
|
||||
containers, Bitcoin RPC, ElectrumX TCP, and manifest port-drift checks, but
|
||||
did not complete cleanly: `botfights` and `filebrowser` remained in
|
||||
`restarting` longer than the matrix window, and the LND `lncli getinfo`
|
||||
probe hung. Do not run the destructive gate until those live-node issues are
|
||||
understood.
|
||||
- After the node updated to `1.7.116-alpha`, `botfights`, `filebrowser`, and
|
||||
`lnd` were active/running and ports `8083`/`9100` were held by Podman's
|
||||
`rootlessport` as expected. The packaged `fips.service` remained installed
|
||||
and enabled but inactive, so the native FIPS service fallback should still
|
||||
ship before the public launch.
|
||||
|
||||
Still required before public publish:
|
||||
|
||||
@@ -58,6 +90,10 @@ Still required before public publish:
|
||||
- Finish Phase 1 password/node/token sanitization beyond the two API keys.
|
||||
- Publish from fresh history after the sanitized tree is final.
|
||||
- Run full Rust, frontend, Android, and lifecycle gate verification.
|
||||
- Resolve the live-node lifecycle blockers above, then rerun the read-only
|
||||
suite followed by the destructive gate only on an approved verification node.
|
||||
- Decide the canonical Archipelago maintainer npub and merge-maintainer npub
|
||||
list before publishing the Nostr Git source-hosting workflow.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,252 @@
|
||||
# Nostr Git Source Hosting Plan
|
||||
|
||||
This plan describes how Archipelago can publish and accept contributions to its
|
||||
source code through `ngit`, NIP-34, and GRASP while keeping the developer
|
||||
experience inside Archipelago.
|
||||
|
||||
## Goals
|
||||
|
||||
- Publish Archipelago source from a sanitized, fresh-history repository.
|
||||
- Make the in-app registry the primary onboarding path for contributors.
|
||||
- Let contributors clone, branch, push PR branches, open PRs, and discuss issues
|
||||
with a Nostr identity from their Archipelago node.
|
||||
- Follow the Bitcoin Core development model: broad public review and easy forks,
|
||||
with canonical merge authority held by a small maintainer set.
|
||||
- Give contributors full read, fork, and proposal rights, but no direct merge
|
||||
rights on the canonical repository.
|
||||
- Keep the official maintainer identity and merge authority separate from user
|
||||
node identities.
|
||||
|
||||
## Current Building Blocks
|
||||
|
||||
Archipelago already has most of the primitives needed for this:
|
||||
|
||||
- App manifests and the app registry already install developer tooling as
|
||||
rootless Podman apps.
|
||||
- The `gitea` app provides a conventional fallback Git UI and package registry.
|
||||
- The app launcher already exposes a consent-gated NIP-07 bridge for launched
|
||||
apps using `getPublicKey`, `signEvent`, NIP-04, and NIP-44 requests.
|
||||
- The backend exposes node and identity Nostr signing RPC methods.
|
||||
- FIPS gives nodes a stable mesh identity and private transport path, but repo
|
||||
announcements and PRs should remain NIP-34 compatible on normal Nostr relays.
|
||||
- DWN protocol registration exists and can be used later for local contribution
|
||||
metadata/cache, but should not be required for the first public workflow.
|
||||
|
||||
## Protocol Basis
|
||||
|
||||
Use existing Nostr Git conventions rather than inventing an Archipelago-only
|
||||
protocol:
|
||||
|
||||
- NIP-34 repository announcement events identify repositories with kind `30617`.
|
||||
- NIP-34 repository state events publish branch/tag refs with kind `30618`.
|
||||
- NIP-34 patches, pull requests, PR updates, issues, and status events use kinds
|
||||
`1617`, `1618`, `1619`, `1621`, and `1630`-`1633`.
|
||||
- `ngit` provides the `git-remote-nostr` helper for `nostr://` clone URLs and PR
|
||||
branches.
|
||||
- GRASP servers provide Git Smart HTTP storage while Nostr events remain the
|
||||
authority for repository identity, refs, PRs, issues, and maintainer state.
|
||||
|
||||
Primary references:
|
||||
|
||||
- https://nips.nostr.com/34
|
||||
- https://docs.rs/crate/ngit/latest/source/README.md
|
||||
- https://ngit.dev/grasp/
|
||||
|
||||
## Recommended Architecture
|
||||
|
||||
### Apps
|
||||
|
||||
Create two first-party apps:
|
||||
|
||||
- `ngit`: CLI/runtime package containing `ngit` and `git-remote-nostr`.
|
||||
- `archipelago-source`: web UI for cloning Archipelago source, viewing NIP-34
|
||||
issues/PRs, opening branches, and submitting PR events.
|
||||
|
||||
The `archipelago-source` app should depend on `ngit`. It can also recommend
|
||||
Gitea for users who want a conventional local web Git UI, but Gitea should not
|
||||
be the source of truth for public contribution permissions.
|
||||
|
||||
### Contributor Onboarding
|
||||
|
||||
When the user installs `archipelago-source` from the registry:
|
||||
|
||||
1. Show a modal before first launch: "Contribute to Archipelago".
|
||||
2. Explain that the app will use their Archipelago Nostr identity to clone and
|
||||
sign contribution events.
|
||||
3. Display the maintainer repository announcement, clone URL, maintainer npub,
|
||||
and relay/GRASP endpoints.
|
||||
4. Ask for consent to:
|
||||
- fetch repository metadata from configured relays,
|
||||
- clone source through `nostr://`,
|
||||
- create local branches,
|
||||
- sign NIP-34 issue/PR/comment events,
|
||||
- push PR branches to approved GRASP servers.
|
||||
5. Store approval per app origin, identity id, repository id, and relay set.
|
||||
|
||||
This should build on the existing NIP-07 app-launcher bridge, but use a more
|
||||
specific permission scope than the generic sign-event approval.
|
||||
|
||||
### Identity And Permissions
|
||||
|
||||
Use four identity classes:
|
||||
|
||||
- `archipelago-maintainer`: an offline or tightly controlled Nostr key that
|
||||
signs the canonical kind `30617` repo announcement and status/merge events.
|
||||
- `archipelago-merge-maintainer`: one of the small set of maintainer npubs
|
||||
allowed to advance canonical refs and publish valid merged/applied status.
|
||||
- `archipelago-build`: release automation key for signed release artifacts and
|
||||
CI status events. It must not have merge authority.
|
||||
- `contributor`: user node or app-specific identity used for PRs, issues, and
|
||||
comments.
|
||||
|
||||
Contributor rights:
|
||||
|
||||
- Clone the repository.
|
||||
- Open issues.
|
||||
- Push proposal branches using `pr/<npub>/<short-topic>` or `pr/<event-id>`.
|
||||
- Publish NIP-34 PR/update/comment events.
|
||||
- Rebase and update their own PR branch.
|
||||
- Run local validation and attach status evidence.
|
||||
|
||||
Contributor restrictions:
|
||||
|
||||
- Cannot update `refs/heads/main` or release branches in canonical state.
|
||||
- Cannot publish maintainer-valid merge/applied status.
|
||||
- Cannot alter the canonical repository announcement.
|
||||
- Cannot publish release catalog signatures.
|
||||
|
||||
Maintainer rights:
|
||||
|
||||
- Publish/update the canonical repo announcement.
|
||||
- Publish canonical `refs/heads/main` state.
|
||||
- Mark PRs merged/closed/draft via NIP-34 status events.
|
||||
- Sign release tags and catalog updates.
|
||||
|
||||
Fork rights:
|
||||
|
||||
- Any contributor can create their own NIP-34 kind `30617` repository
|
||||
announcement for a fork.
|
||||
- Fork announcements should use the NIP-34 `u` tag to point back to the
|
||||
canonical `archy` repository.
|
||||
- The source app should make forking a first-class path: "Fork on Nostr", clone
|
||||
the fork locally, push branches to the contributor's GRASP list, and open PRs
|
||||
back to canonical Archipelago when they want review.
|
||||
- Forks can have their own maintainer npubs, relays, policies, and release
|
||||
cadence, but the app should clearly label them as forks unless signed by the
|
||||
canonical maintainer set.
|
||||
|
||||
The GRASP server policy should enforce this by accepting pushes to maintainer
|
||||
refs only when backed by signed maintainer state, while allowing contributor PR
|
||||
refs from their own npubs.
|
||||
|
||||
## Repository Layout
|
||||
|
||||
Canonical repo announcement:
|
||||
|
||||
- repo id: `archy`
|
||||
- display name: `Archipelago`
|
||||
- clone URLs:
|
||||
- `nostr://<maintainer-npub>/<relay-hint>/archy`
|
||||
- `https://<grasp-host>/<maintainer-npub>/archy.git`
|
||||
- relays:
|
||||
- Archipelago-operated relay
|
||||
- at least two public Nostr relays that support the event load
|
||||
- GRASP servers:
|
||||
- Archipelago-operated GRASP instance
|
||||
- one public GRASP-compatible mirror
|
||||
|
||||
Keep the existing HTTP Git remote as a mirror during launch. The docs can
|
||||
present `nostr://` as the preferred contribution path once the workflow is
|
||||
proven.
|
||||
|
||||
## UI Requirements
|
||||
|
||||
The source app should provide:
|
||||
|
||||
- A first-run contribution modal with a real Archipelago source graphic, not a
|
||||
generic text-only dialog.
|
||||
- Current clone status and local path.
|
||||
- Branch list, changed files, commit form, and push/open-PR flow.
|
||||
- PR inbox, issue list, maintainer status, and relay health.
|
||||
- Explicit identity indicator showing which npub will sign events.
|
||||
- A merge rights indicator that clearly says contributors can propose changes
|
||||
but cannot merge them.
|
||||
- A fork flow that creates a user-owned NIP-34 repo announcement and remote,
|
||||
then offers "Open PR to Archipelago" from any fork branch.
|
||||
- Maintainer badges based only on pinned canonical maintainer npubs, not relay
|
||||
metadata or server-side account names.
|
||||
- Links to container docs, deployment docs, manifest spec, and open-source
|
||||
readiness tasks.
|
||||
|
||||
## Backend Work
|
||||
|
||||
Add an RPC module for source contribution workflow:
|
||||
|
||||
- `source.repo-info`: returns canonical announcement, clone URL, relay set,
|
||||
maintainer npubs, and local clone state.
|
||||
- `source.ensure-ngit`: verifies the `ngit` app/runtime is installed.
|
||||
- `source.clone`: clones or updates the local source checkout.
|
||||
- `source.status`: returns branch, dirty files, ahead/behind, and PR state.
|
||||
- `source.commit`: creates a local commit from selected files.
|
||||
- `source.fork`: creates a contributor-owned NIP-34 fork announcement and local
|
||||
remote.
|
||||
- `source.open-pr`: pushes a PR branch and publishes a kind `1618` event.
|
||||
- `source.update-pr`: updates the branch and publishes kind `1619`.
|
||||
- `source.issue`: publishes a kind `1621` event.
|
||||
|
||||
Backend must shell out through a narrow command wrapper, never arbitrary user
|
||||
commands. The wrapper should set an isolated working tree under
|
||||
`/var/lib/archipelago/source/archy`, run as the Archipelago service user, and
|
||||
deny operations outside that path.
|
||||
|
||||
## Security Model
|
||||
|
||||
- Never expose maintainer private keys to an Archipelago node.
|
||||
- Prefer app-specific contributor identities over the node's default identity.
|
||||
- Require per-action consent for first PR push, issue creation, and signing any
|
||||
event that tags the canonical repository.
|
||||
- Pin the canonical maintainer npub in the app manifest and backend config.
|
||||
- Keep the canonical merge-maintainer allow list signed by the
|
||||
`archipelago-maintainer` key; never infer merge rights from GRASP server
|
||||
accounts.
|
||||
- Verify the canonical kind `30617` event signature before displaying clone
|
||||
instructions.
|
||||
- Treat GRASP servers as untrusted storage; verify Git refs against signed
|
||||
Nostr state.
|
||||
- Do not use destructive git operations from the UI without an explicit modal.
|
||||
- Store local clones and generated patches outside app container writable roots
|
||||
unless the user exports them.
|
||||
|
||||
## MVP
|
||||
|
||||
1. Package `ngit` as a first-party app.
|
||||
2. Stand up one Archipelago-operated GRASP server and one Nostr relay.
|
||||
3. Publish sanitized fresh-history `archy` through `ngit init`.
|
||||
4. Add a simple `archipelago-source` app that clones source and links out to the
|
||||
preferred Nostr Git browser.
|
||||
5. Add app-launcher consent scopes for repository-specific NIP-34 signing.
|
||||
6. Allow issues and PR branch submission from contributor npubs.
|
||||
7. Add a one-click fork flow that publishes a contributor-owned fork
|
||||
announcement referencing canonical Archipelago.
|
||||
8. Keep maintainer merge/status publication manual.
|
||||
|
||||
## Later
|
||||
|
||||
- Native PR review UI with file diffs and inline comments.
|
||||
- CI status events signed by the build identity.
|
||||
- FIPS-first source sync between trusted Archipelago nodes.
|
||||
- Private prerelease repositories using NIP-42 allow lists and/or protected
|
||||
events if the ecosystem support is mature enough.
|
||||
- Multi-maintainer policy with threshold signatures or explicit maintainer-list
|
||||
rotation events.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Which maintainer npub should become canonical for `archy`?
|
||||
- Should contributor identities be node-default or app-specific by default?
|
||||
- Which GRASP implementation should be deployed first: `ngit-grasp` or another
|
||||
NIP-34/GRASP-compatible relay?
|
||||
- Should the source app include a full web Git UI in v1, or launch Gitea/ngit
|
||||
browser links for review while keeping signing/submission native?
|
||||
- What exact license and contribution certificate should contributors accept
|
||||
before submitting PR events?
|
||||
Reference in New Issue
Block a user