Files
app/old
2026-10-04 02:57:30 +00:00
..
2026-10-04 02:57:29 +00:00
2026-10-04 02:57:28 +00:00
2026-10-04 02:57:30 +00:00
…
2026-10-04 02:57:30 +00:00

Persimmons 🍊

permissions, without the ceremony.

Passwords, PATs & plenty of other useful P's for humans + agents.

Persimmons is a small reusable-object layer over Gitea's existing user/repository Actions secrets + variables. Credentials are first; people / contacts remain a natural future Persimmon without being part of v0.

Live surface: https://🍵.teahub.xyz/🍊/

Product / secret naming

For new credential-backed Persimmons, the normalized Persimmon name is also the actual Gitea secret name and the card title.

MY_USEFUL_PASSWORD
→ Gitea secret: MY_USEFUL_PASSWORD
→ Persimmon title: MY_USEFUL_PASSWORD

Names normalize to Gitea-safe uppercase underscore form. Persimmons refuses to create over an existing secret with the same name.

Older objects created with PERSIM_SECRET_<id> remain fully supported; they are not silently renamed because their stored value is intentionally unreadable.

Identity boundary

The browser acts as the signed-in human:

🍊 page
→ teahub.xyz /tea/chat/persimmons/*
→ Tea verifies the Gitea web session
→ Tea uses that same signed-in Gitea session for Actions settings
→ caller Gitea permissions remain the effective boundary

Gitea's web session is not replayed as REST API authentication. Gitea 1.27 writes use same-origin request protection (Origin / Referer / same-origin fetch context), not the removed hidden _csrf token model.

MCP/agent reads use the MCP caller's OAuth identity. There is no service-account or hardcoded-user fallback.

Vault model

Persimmons
├── My vault
│   └── user Actions secrets + variables
└── Repository vaults
    └── caller-authorized repository Actions secrets + variables

Existing Gitea secrets without Persimmons metadata are projected safely as legacy Persimmons using only Gitea-visible name, scope/context and availability. Provider/account/scopes are never fabricated.

Security boundary

human/browser provides a new value
→ selected Gitea protected store receives it
→ Persimmons exposes safe metadata + availability
→ stored value is never revealed back

No reveal/copy-after-storage endpoint exists.

Lifecycle: create → list → rotate → revoke → delete.

Contextual-use seam

Future tools should be able to ask Persimmons for authority in context:

domain()
→ Cloudflare connection required
→ choose/add Persimmon
→ bounded operation
→ domain() resumes

The generalized choose/use/resume framework, OAuth setup, people/contacts, and moving/sharing objects between vaults remain future work.