Zero‑trust local secret vault. Frontend performs encryption/decryption, backend only stores encrypted payloads and handles window workflow.

- Frontend (browser): crypto core (HKDF + SM4 + HMAC‑SM3)
- Backend (Gin): encrypted storage + window scheduler
- Storage: local JSON files (
configs.json,windows.json,audit.log)
- User enters
globalKey(never sent to backend). - Frontend derives
env_keywith HKDF:env_key = HKDF_SM3(globalKey, kdf_salt, name)
- Frontend encrypts each key/value:
e_key = SM4_CBC(env_key, key)e_value = SM4_CBC(env_key, value)
- Frontend signs:
sign = HMAC_SM3(env_key, JSON.stringify([{e_key, e_value}, ...]))
- Frontend sends encrypted data to backend:
POST /api/nests/config/add(create)POST /api/nests/config/update(update)
- On create, backend generates Google Authenticator QR (label:
Nests:name).
- Backend writes encrypted data to
data/configs.json. - No plaintext is stored.
- Updates are atomic (temp file + fsync + rename).
- Audit log is appended to
data/audit.log.
- Terminal requests a window:
GET /api/nests/server/get?name=xxx
- Backend returns
wid+checker_web. - User opens
checker_weband inputsglobalKey. - Frontend verifies Google Authenticator code (OTP) for this env.
- Frontend fetches
kdf_salt, derivesenv_key, then submits:POST /api/nests/server/windowswithenv_key(no globalKey).
- Backend stores
env_keyin memory only for this window.
- Internal service calls:
GET /api/nests/server/plaintext?wid=xxx
- Backend decrypts using in‑memory
env_keyand returns plaintext JSON. - Each window allows 2 reads max.
- After 2 reads, window is invalidated and
env_keyis cleared.
GET /api/nests/config/listGET /api/nests/config/get?name=xxxPOST /api/nests/config/updatePOST /api/nests/config/addPOST /api/nests/config/otp/verifyGET /api/nests/server/get?name=xxxPOST /api/nests/server/windows(env_key confirmation)GET /api/nests/server/windows/check?wid=xxxGET /api/nests/server/plaintext?wid=xxx(internal only)
package main
import (
"fmt"
"log"
"nests/sdk"
)
func main() {
client := sdk.Init("http://localhost:7766")
val, err := client.GetConfig("dev", "jwt")
if err != nil {
log.Fatal(err)
}
fmt.Println("jwt:", val)
}Behavior:
- Prints
checker_webURL to stdout - Blocks and polls window status
- When ready, calls
/server/plaintextand returns the key’s value - Timeout/expiry exits with error
go mod tidy
go run .cd /Users/pangaichen/Desktop/shitCode/nests
# configure backend API base (optional)
NESTS_API_BASE=http://localhost:7766 go run ./cmd/frontBackend:
NESTS_PORT(default7766)NESTS_DATA_DIR(default./nests/data)NESTS_CHECKER_WEB_BASE(defaulthttp://localhost:7788/checker)NESTS_FORCE_HTTPS(set1to force HTTPS + HSTS)
Frontend:
- Templates in
front/templates - Static assets in
front/static NESTS_API_BASE(defaulthttp://localhost:7766)NESTS_FORCE_HTTPS(set1to force HTTPS + HSTS)
If running in Docker:
Use Dockerfile
-
File paths
NESTS_DATA_DIRmust point to a writable volume (e.g./data).
-
CORS & CSP
- Frontend CSP currently allows
http://localhost:7766. - Update CSP and API base if using different hostnames.
- Frontend CSP currently allows
-
Internal plaintext API
/api/nests/server/plaintextis restricted to private IPs.- In Docker, requests may appear as bridge IPs. Ensure your container network still matches private CIDRs.
-
Memory-only env_key
env_keyis stored in backend memory only.- Restarting backend clears all pending windows.
-
Clock/time
- Window expiry depends on server time. Ensure container time is correct.
- Backend never receives or stores
globalKey. - Plaintext API is limited to internal networks and max 2 reads per window.
- Google Authenticator OTP is required before entering globalKey in checker.
- CSP forbids inline scripts; HSTS is enabled (effective only on HTTPS).
- If you need stricter controls (token, mTLS, allowlist), add them at the gateway.