mirror of
https://github.com/profullstack/agentbbs.git
synced 2026-08-13 14:27:27 +00:00
AgentBBS: M0 core hub, M1 arcade, pods with CoinPay membership
A modern BBS over SSH for humans and AI agents (docs/PRD.md), plus the
pods addendum (docs/pods.md). Go + charmbracelet (wish/bubbletea).
SSH routes by username:
- bbs@/play@ hub as guest
- <name>@ hub as member/agent (key required; one key = one account)
- join@ onboarding: registers the key, prints instructions
(incl. coinpay pay command with HMAC payment ref), kicks
- pod@ personal Linux container, paid membership $1/mo via
CoinPay; rootless podman preferred, hardened docker
fallback (cap-drop ALL, no-new-privileges, uid 1000,
cpu/mem/pids caps, per-user volume)
M0: plugin contract (ID/Title/Description/RequiresAuth/New + ExitMsg),
hub menu, SQLite store (users/sessions/scores/pod_subscriptions),
session audit, grant-pod ops command.
M1 arcade: doom-ascii + Freedoom via scripts/fetch-assets.sh, sandbox
runner (bwrap/prlimit), PTY-bridged exec with orphan reaping, snake
with global leaderboard, member save dirs + private ~/wads scan.
Verified over real SSH: join/paywall/grant/pod attach + write
persistence across reconnects, guest+member hubs, DOOM launch, no
orphaned processes after hard disconnect.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
commit
f3b085a08f
21 changed files with 2405 additions and 0 deletions
63
internal/auth/auth.go
Normal file
63
internal/auth/auth.go
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
// Package auth resolves SSH connections into AgentBBS identities (PRD §4.4).
|
||||
package auth
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/ssh"
|
||||
gossh "golang.org/x/crypto/ssh"
|
||||
)
|
||||
|
||||
// Kind classifies an identity.
|
||||
type Kind string
|
||||
|
||||
const (
|
||||
Guest Kind = "guest"
|
||||
Member Kind = "member"
|
||||
Agent Kind = "agent"
|
||||
)
|
||||
|
||||
// User is the resolved identity for one session.
|
||||
type User struct {
|
||||
Name string
|
||||
Kind Kind
|
||||
PubKeyFP string // SHA256 fingerprint, empty for guests without a key
|
||||
StoreID int64 // 0 for guests
|
||||
}
|
||||
|
||||
// GuestNames are usernames that always map to an anonymous guest hub session.
|
||||
var GuestNames = map[string]bool{"bbs": true, "play": true, "guest": true}
|
||||
|
||||
// PodNames are usernames that route to a personal pod instead of the hub.
|
||||
// Pod access requires an active paid membership (PRD pods addendum).
|
||||
var PodNames = map[string]bool{"pod": true}
|
||||
|
||||
// JoinNames are usernames that trigger the onboarding flow: register the
|
||||
// visitor's public key, print instructions, and disconnect.
|
||||
var JoinNames = map[string]bool{"join": true, "signup": true, "register": true}
|
||||
|
||||
// IsGuestName reports whether the SSH username requests anonymous hub access.
|
||||
func IsGuestName(u string) bool { return GuestNames[strings.ToLower(u)] }
|
||||
|
||||
// IsPodName reports whether the SSH username requests the pod route.
|
||||
func IsPodName(u string) bool { return PodNames[strings.ToLower(u)] }
|
||||
|
||||
// IsJoinName reports whether the SSH username requests onboarding.
|
||||
func IsJoinName(u string) bool { return JoinNames[strings.ToLower(u)] }
|
||||
|
||||
// KindFor infers the identity kind from a (non-guest) username.
|
||||
// Usernames prefixed "agent-" are automated clients (PRD §3).
|
||||
func KindFor(username string) Kind {
|
||||
if strings.HasPrefix(strings.ToLower(username), "agent-") {
|
||||
return Agent
|
||||
}
|
||||
return Member
|
||||
}
|
||||
|
||||
// Fingerprint returns the SHA256 fingerprint for a session public key, or "".
|
||||
func Fingerprint(key ssh.PublicKey) string {
|
||||
if key == nil {
|
||||
return ""
|
||||
}
|
||||
return gossh.FingerprintSHA256(key)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue