Villa Market secrets
API keys and passwords for Villa services, encrypted at rest. People sign in with their SSH key. Services read with their AWS role, so no service stores a credential to fetch its credentials.
villa-commerce. Each group lists the SSH keys and AWS roles it trusts.PeopleInstall the command and sign in
curl -fsSL https://secrets.villamarket.ai/villa-secret -o ~/.local/bin/villa-secret
chmod +x ~/.local/bin/villa-secret
villa-secret whoami # your key, admin or not, your groups
It uses ~/.ssh/id_ed25519 (or id_ecdsa, id_rsa; --key to choose) through ssh-keygen -Y sign, with ssh-agent if it's running. Python 3 and OpenSSH are all it needs.
| Command | What it does |
|---|---|
villa-secret put villa-commerce AGENT_LLM_API_KEY | Asks for the value with hidden input (--dialog for a macOS pop-up, --stdin to pipe it) and stores it. |
villa-secret ls · villa-secret ls villa-commerce | Your groups, or the secret names in one, with version and who last changed each. |
villa-secret get villa-commerce AGENT_LLM_API_KEY | Prints the value (members of the group only). |
villa-secret console | Opens the admin console in your browser, signed in for 15 minutes. |
Never paste a secret into a chat, a ticket or an env file. put takes it from a hidden prompt, straight to this service.
ServicesRead a secret with the service's AWS role
An admin adds the service's IAM role ARN to the group as a reader. The service then signs an sts:GetCallerIdentity request with its own credentials; this server passes it to AWS STS to learn the role and returns the value if the group lists it.
# in the service (any AWS Lambda Python runtime has botocore)
curl -fsSL https://secrets.villamarket.ai/client.py -o villa_secrets_client.py
from villa_secrets_client import fetch_secret
api_key = fetch_secret("villa-commerce", "AGENT_LLM_API_KEY") # cache it; don't log it
The signed request names this server in a signed header (x-villa-secrets-server: secrets.villamarket.ai), so it cannot be replayed against another service, and this server sends it only to sts.*.amazonaws.com.
AdminsGroups, approved keys and readers
In the admin console, admins create groups. For each group they list the SSH public keys allowed to write and read it, and the AWS role ARNs allowed to read it. The console also shows the audit log of sign-ins, writes and reads. Admins are the bootstrap GitHub users' SSH keys plus keys added in the console. Admins manage groups but read values only if their key is also listed on the group.
How it worksEncryption and storage
- Each value is sealed with AES-256-GCM, bound to its group and name, and stored in DynamoDB. There is no plaintext at rest.
- The only key is a random 256-bit data key in AWS Systems Manager Parameter Store (secure string, standard tier). Only this service's Lambda can read it.
- Challenges are single-use and expire in 2 minutes; console sessions last 15 minutes; the audit log is kept 180 days.
- It runs on AWS Lambda behind CloudFront, with no servers.