78 lines
2.6 KiB
Markdown
78 lines
2.6 KiB
Markdown
# 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.
|