English | Español | Français | Deutsch | Português (BR)
Traducción al español de README.md. El texto original en inglés es la versión oficial y prevalece en caso de discrepancias.
Sincronización de secretos con cifrado de extremo a extremo para equipos de desarrollo. Deja de enviar tu .env por Slack.
Warning
Sotto es una versión previa a la 1.0 y no ha pasado una auditoría criptográfica de terceros. Funciona de extremo a extremo, pero aún no deberías confiarle secretos críticos de producción. Consulta SECURITY.md.
Sotto se basa en una única implementación criptográfica en Rust compartida por la CLI nativa y el cliente del navegador mediante WebAssembly. El servidor almacena y sincroniza datos cifrados sin recibir nunca secretos en texto plano ni claves utilizables.
Sotto es un único producto de código abierto que puedes usar de tres formas. Elijas la que elijas, el servidor solo almacena texto cifrado.
| Modo | Qué obtienes |
|---|---|
| Local | La CLI y una bóveda cifrada en tu propia máquina. Sin cuenta y sin servidor. |
| Autoalojado | El mismo servidor Apache-2.0 en infraestructura que tú operas. No aplica límites de plan ni comprobaciones del servicio alojado; consulta Autoalojamiento. |
| Sotto Cloud | El servidor que Sotto opera en getsotto.co.uk, para cuando prefieres no gestionar uno. sotto login lo usa por defecto. Los planes y límites están en la página de precios, y el estado del servicio, en status.getsotto.co.uk. |
Puedes empezar en local y añadir un servidor más adelante: después de sotto login, sotto push
sube el entorno activo tal como está.
El flujo de extremo a extremo funciona: cifra en local, sincroniza texto cifrado, descifra en otro dispositivo o en el navegador, y comparte un único secreto con un enlace de un solo uso. Los equipos también funcionan de extremo a extremo: organizaciones con roles, concesiones de entorno por miembro, rotación de claves al eliminar a un miembro, tokens de máquina para CI, un registro de auditoría de la organización y el restablecimiento de la cuenta si se pierde el Emergency Kit.
| Componente | Disponible ahora |
|---|---|
| Núcleo criptográfico | KDF, AEAD XChaCha20-Poly1305 + AAD, encapsulado de claves, concesiones mediante sealed box X25519, la jerarquía de bóvedas de entorno, reencapsulado de claves de datos (rotación), criptografía de enlaces para compartir y codificación de claves, con vectores de referencia nativo↔WASM, fuzzing de los códecs y pruebas Kani del análisis de cabeceras de sobre y de símbolos de clave |
| CLI | Secretos locales (init, set, get, ls, rm, import, export, run), entornos (env ls/use/diff/copy), un panel interactivo, sincronización login/push/pull, setup para dispositivos nuevos, history y rollback, enlaces de un solo uso (share, shares ls/revoke); equipos: org create/ls/invite/members/remove/plan/audit, grant, clone, rotate, token create/ls/revoke de máquina con caducidad (con modo SOTTO_TOKEN para CI); status, cloud status, reset por pérdida del kit de emergencia, temas y completado del shell |
| Servidor | Inicio de sesión OAuth + sesiones, sincronización de cuentas + instantáneas (escrituras versionadas, ETag), organizaciones + membresías + roles, concesiones de claves de bóveda por miembro, rotación transaccional de claves, tokens de máquina con caducidad, historial de secretos, un registro de auditoría de la organización, eliminación opcional de organizaciones con un periodo de recuperación, restablecimiento de cuentas y enlaces de un solo uso - solo texto cifrado. Una implementación de Sotto Cloud también aplica límites de plan y puede facturar mediante Stripe |
| Web | Una página de inicio y guías; la bóveda en /app, que se desbloquea en el navegador para explorar, buscar, mostrar y copiar secretos, crear enlaces de un solo uso, compartir un entorno con un miembro y rotar la clave de un entorno; un panel de equipo con organizaciones, miembros, invitaciones por correo, el plan, el registro de auditoría y la eliminación de organizaciones; la página de recepción de enlaces de un solo uso; y una página de cuenta de Sotto Cloud en /cloud |
Binarios firmados y precompilados para macOS (Apple Silicon + Intel), Linux (x86_64 + ARM64) y Windows x86_64:
curl -fsSL https://raw.githubusercontent.com/getsotto/sotto/main/install.sh | shirm https://raw.githubusercontent.com/getsotto/sotto/main/install.ps1 | iexEl instalador verifica la suma de comprobación SHA-256 del archivo comprimido, y su firma Sigstore cuando cosign
está instalado, antes de instalar (~/.local/bin en macOS/Linux, %LOCALAPPDATA%\sotto\bin en
Windows). ¿Prefieres revisar antes? Descarga un archivo comprimido desde la
página de versiones y verifícalo manualmente según
SECURITY.md, o compila desde el código fuente (consulta Desarrollo).
Los instaladores, la fórmula de Homebrew y la acción de GitHub instalan versiones publicadas,
mientras que este README sigue la rama main, que puede ir por delante de la última versión. Por
eso es posible que un comando descrito aquí aún no exista en la versión que tienes instalada;
sotto --help muestra los comandos que admite tu versión.
El tap de Sotto ofrece otra vía de instalación para macOS. La fórmula empaqueta versiones de la CLI revisadas y requiere macOS 15 o posterior. Apple Silicon es la plataforma principal; Intel se ofrece como mejor esfuerzo y Homebrew Tier 3. Homebrew prevé finalizar el soporte para Intel en septiembre de 2027 o después. Consulta la guía de soporte e instalación del tap y el registro de preparación para el lanzamiento antes de usarlo. Evita esta versión preliminar para secretos críticos de producción.
Instala y actualiza la fórmula con:
brew install getsotto/tap/sottobrew update
brew upgrade getsotto/tap/sottoSi hay otra instalación de sotto en tu PATH, inspecciona los ejecutables
resueltos y el binario de Homebrew antes de elegir cuál usar:
which -a sotto
brew list --versions sotto
"$(brew --prefix)/bin/sotto" --versionPara eliminar solo la fórmula de Homebrew, ejecuta:
brew uninstall getsotto/tap/sottoAl desinstalar la fórmula se conservan los archivos del proyecto, los datos
locales de Sotto, las entradas del Llavero y otras instalaciones de sotto.
Confirma qué binario está seleccionado y guarda tu Kit de emergencia
antes de eliminar o cambiar una instalación existente.
sotto completions <shell> muestra un script de completado en la salida estándar. Por ejemplo:
# bash
mkdir -p ~/.local/share/bash-completion/completions
sotto completions bash > ~/.local/share/bash-completion/completions/sotto
# zsh (add the directory to fpath in ~/.zshrc first)
mkdir -p ~/.zfunc
sotto completions zsh > ~/.zfunc/_sotto
# fish
mkdir -p ~/.config/fish/completions
sotto completions fish > ~/.config/fish/completions/sotto.fishLos tarballs y zips de las versiones también contienen los archivos correspondientes completions/sotto.*
si prefieres copiarlos directamente.
Para GitHub Actions, usa la acción Sotto Setup para
instalar una versión exacta de la CLI y verificar su suma de comprobación y sus bundles Sigstore antes de dejar sotto
disponible para los pasos siguientes:
jobs:
ci:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
- uses: getsotto/sotto-action@v1.1.0
with:
sotto-version: v0.9.0
- run: sotto run -- npm test
env:
SOTTO_SERVER: ${{ vars.SOTTO_SERVER }}
SOTTO_TOKEN: ${{ secrets.SOTTO_TOKEN }}La referencia de la acción y sotto-version son independientes. Mantén sotto-version como una
versión exacta vX.Y.Z. Define la variable de repositorio SOTTO_SERVER con la URL de tu servidor,
también https://getsotto.co.uk para Sotto Cloud: con SOTTO_TOKEN definido, sotto run y
sotto export nunca recurren a un servidor predeterminado, así que el token solo llega a un servidor
que hayas indicado. Consulta la documentación de la acción
para ejemplos de matrices, Windows y flujos reutilizables.
¿Quieres una demo funcional? sotto-example muestra la inyección local de secretos con un GIF de Python y pasos copiables, además de pequeños ejemplos en JavaScript, TypeScript, Java, C#, PHP, Go y C++. No necesitas cuenta; las instrucciones cubren macOS, Linux y Windows.
sotto init # create your identity + first project - SAVE the printed Emergency Kit
sotto set DATABASE_URL # hidden prompt; encrypted locally before it ever touches disk
sotto import .env # optional: pull in an existing file, still encrypted locally
sotto run -- npm start # inject the environment's secrets into any command
sotto get DATABASE_URL -c # copy a secret without printing it; clipboard clears after 45s when unchanged
sotto export --format dotenv --reveal # print a .env; refuses a terminal without --revealsotto init crea los entornos dev, staging y prod y selecciona dev. Exportar escribe texto
plano, por lo que necesita --reveal en un terminal, igual que sotto get; --format también admite
shell y json. El borrado del portapapeles es una medida de mejor esfuerzo: si reemplazas el
contenido se protege el nuevo valor, mientras que los gestores del portapapeles, la suspensión o la
terminación del proceso auxiliar pueden conservar una copia.
Hasta aquí todo se queda en tu máquina. Para sincronizar otro dispositivo, trabajar en equipo o usar CI, inicia sesión en un servidor:
sotto login # Sotto Cloud by default; --server <url> for your own server
sotto push # upload the active environment's ciphertext
sotto share DATABASE_URL # a one-time link whose key never reaches the serversotto login abre un navegador para iniciar sesión con GitHub. Usa Sotto Cloud en
getsotto.co.uk salvo que indiques --server <url> (consulta
Autoalojamiento para alojar el tuyo), y los comandos posteriores reutilizan el
servidor que elegiste. En cualquier caso el servidor solo almacena texto cifrado: la bóveda web en
/app del mismo servidor descifra en tu navegador, con claves que nunca salen de tus dispositivos.
Para explorar los secretos de forma interactiva, consulta la guía del panel.
sotto login # same account as the first machine
sotto setup # unpack the Emergency Kit onto this device
sotto pull # download the ciphertext you already pushedNecesitas el Emergency Kit que imprime sotto init; sin él, un dispositivo nuevo no puede descifrar la bóveda.
Si pierdes el Emergency Kit, sotto reset da claves nuevas a tu cuenta. Es un restablecimiento, no
una recuperación: todo lo cifrado con las claves antiguas queda ilegible para siempre, y los
administradores de la organización deben volver a concederte los entornos compartidos. Si algún
dispositivo todavía puede desbloquear la bóveda, exporta antes lo que necesites.
Usa --env para elegir un entorno para un solo comando sin cambiar el entorno predeterminado del proyecto:
sotto run --env staging -- npm test
sotto ls --env staging--env se aplica solo a ese comando; sotto env use cambia el entorno predeterminado.
Lista los entornos, cambia el predeterminado, compara dos o previsualiza una copia entre ellos:
sotto env ls # list environments; the active one is marked
sotto env use staging # switch the project's active environment
sotto env diff dev staging # compare keys; values stay hidden without --reveal
sotto env copy dev staging # preview additions and updates without writing
sotto env copy dev staging --confirm # apply the copy; never delete destination keysenv diff marca cada clave con = (mismo valor), ! (valores distintos), < (solo en el primer
entorno) o > (solo en el segundo). Sin --confirm, la copia es una simulación. Una copia confirmada
añade y actualiza secretos, pero deja intactas las claves que solo existen en el destino.
sotto share cifra un secreto en un enlace de un solo uso. La clave va después del # del enlace,
una parte que los navegadores nunca envían a un servidor, así que el servidor solo guarda texto
cifrado. Crear un enlace requiere sotto login; quien lo recibe no necesita cuenta. Abrir el enlace
no consume una visualización; revelar el secreto sí.
sotto share DATABASE_URL # choose view and lifetime limits in an interactive terminal
sotto share DATABASE_URL --views 3 --expire 3600 # skip both limit prompts
sotto share DATABASE_URL --passphrase # also require a passphrase; send it separatelyEn un terminal interactivo, cada límite omitido abre su propio menú. El menú de visualizaciones
ofrece 1, 2, 3, 5 o 10 visualizaciones y un valor personalizado; el menú de duración ofrece sin
caducidad, 1 hora, 1 día, 7 días, 30 días o un número de segundos personalizado. Los valores
personalizados deben ser de 1 a 100 visualizaciones o de 1 a 2592000 segundos. Proporcionar
DATABASE_URL omite solo la selección del secreto: --views omite el menú de visualizaciones y
--expire omite el menú de duración de forma independiente. Pulsa Esc o Ctrl-C en cualquier menú
de selección para cancelar sin crear un enlace.
El uso no interactivo requiere un nombre de secreto explícito. Cuando se omite cualquiera de los
límites, se aplica su valor predeterminado: una visualización y sin caducidad. Para omitir los tres
menús de selección en un terminal interactivo, proporciona el nombre y ambos límites, por ejemplo
sotto share DATABASE_URL --views 3 --expire 3600. Es posible que todavía se soliciten el
desbloqueo y la frase de contraseña.
Un servidor puede aplicar límites más estrictos a algunas cuentas. Cuando rechaza una solicitud, la CLI muestra el motivo que da el servidor y no crea ningún enlace.
Usa sotto share --no-copy para desactivar la copia interactiva, o --copy para solicitarla explícitamente.
Estas opciones solo controlan el portapapeles; --no-copy no omite los menús de límites del enlace.
Un enlace deja de funcionar cuando se agotan sus visualizaciones, cuando caduca o cuando lo revocas. Revocarlo impide que el servidor siga entregando el texto cifrado, pero no lo borra del servidor:
sotto shares ls # your 100 most recent links: views used, expiry, revocation
sotto shares ls --json
sotto shares revoke <token> # the token is the part of the link between /s/ and #sotto shares ls nunca muestra el texto cifrado ni la clave del enlace.
Los equipos comparten entornos mediante una organización. Cada miembro recibe su propia copia sellada de la clave de un entorno (una concesión), y el servidor comprueba roles y concesiones en cada solicitud sin poder leer nada.
sotto org create acme # prints the org id
sotto init --org <org-id> # an org-owned project
sotto push # create it on the server before sharing
sotto org invite <org-id> dev@example.com # invite an existing Sotto user; prints their user id
sotto grant <user-id> # share the active environment; prints their clone commandEl miembro ejecuta el comando impreso en su propia copia del proyecto:
sotto clone <project-id> <env-id> --org <org-id>Para ver quién tiene acceso, eliminar a alguien o rotar tú mismo la clave de un entorno:
sotto org members <org-id> # members, roles and user ids
sotto org remove <org-id> <user-id> # remove a member and rotate every environment they held
sotto rotate # rotate the active environment's keyEliminar a un miembro rota la clave de todos los entornos a los que tenía acceso y revoca los tokens de máquina que creó en la organización, nombrando cada uno para que puedas volver a crearlo. La rotación protege lo que se escriba después. Los valores que el miembro ya vio siguen expuestos, así que cámbialos en su origen.
sotto org plan <org-id> lee la vista de derechos actual del servidor configurado para esa
organización. Debes haber iniciado sesión (sotto login); el cofre local no necesita estar
desbloqueado. Muestra el nivel asignado, el nivel efectivo (el que aplica los límites ahora), el
fin de la prueba cuando la organización tiene uno, y o bien límites de miembros y proyectos de
organización o limits: none (Team).
Salida ilustrativa en Sotto Cloud para una organización gratuita cuya prueba ha terminado:
tier: free
effective: free
trial: ends 2026-07-16T09:00:00Z
limits: 3 members, 1 org project(s)
Un servidor autoalojado no aplica límites de plan, así que siempre informa team como nivel
efectivo, sean cuales sean el nivel y el fin de prueba que la organización tenga guardados:
tier: free
effective: team
trial: ends 2026-07-16T09:00:00Z
limits: none (Team)
Estos ejemplos son ilustrativos; las organizaciones reales pueden mostrar niveles, pruebas y límites distintos.
Los propietarios y administradores de una organización pueden consultar la actividad reciente del equipo con:
sotto org audit <org-id>
sotto org audit <org-id> --limit 20Usa el ID que imprime sotto org create <name> o que muestra sotto org ls. Los resultados aparecen
primero con los eventos más recientes; el valor predeterminado es de 100 eventos y el servidor limita
--limit al rango 1-500. El comando muestra una línea por evento con el formato timestamp action actor y, de forma opcional, los campos target=..., env=... y (detail). Es una vista acotada de
actividad y metadatos, no una forma de recuperar valores secretos; no ofrece paginación ni un archivo
histórico completo.
En Sotto Cloud, la organización necesita una suscripción Team efectiva, incluido un periodo de prueba Team activo. Las implementaciones autoalojadas omiten esta comprobación del plan, pero quien ejecute el comando debe conservar el rol de propietario o administrador. Si no hay eventos, el comando no muestra filas y termina correctamente.
Un token de máquina permite que la CI o un servicio lean un entorno sin contraseña ni Emergency Kit.
Con SOTTO_TOKEN definido, sotto run y sotto export obtienen y descifran ese entorno en cada
ejecución; define también SOTTO_SERVER, como muestra el ejemplo de GitHub Actions.
Los tokens de máquina caducan. Uno nuevo dura 90 días, salvo que indiques --expires-in-days con
un valor de 1 a 365; sotto token ls muestra cuándo termina cada uno. Dos semanas antes,
sotto run y sotto export muestran un aviso en el registro de la CI.
Los comandos de tokens usan el acceso del usuario con sesión iniciada y el entorno seleccionado.
En un entorno de una organización, solo un administrador o propietario puede gestionar tokens
de máquina. Los listados incluyen solo metadatos de tokens activos: se omiten los revocados y
caducados, y el listado no permite recuperar la credencial que se muestra una sola vez al crear
un token con sotto token create. El JSON incluye token_id, name, created_by,
beneficiary_id, beneficiary_status, expires_at y expires_in_days; los campos de
caducidad pueden ser null. El token_id es el ID que se revoca, no el nombre del token ni el
secreto SOTTO_TOKEN.
Usa estos comandos para consultar, sustituir y revocar un token. La selección del entorno solo se aplica a este comando:
sotto token ls
sotto token ls --json
sotto --env staging token ls --json
sotto token create --name ci
sotto token revoke <token-id>Para sustituir un token de CI, identifica el ID antiguo en el listado, crea uno nuevo, actualiza
el secreto de la CI y verifica que la CI lo use; después revoca el ID antiguo con
sotto token revoke <token-id>. La revocación impide de inmediato que ese token se autentique
en la API, pero no rota la clave del entorno. Para un entorno de una organización, consulta las
instrucciones existentes de sotto rotate cuando sea necesario rotar la clave. Ni la revocación
ni la rotación pueden borrar el texto plano que ya se haya copiado.
Desde un proyecto inicializado, ejecuta sotto sin subcomandos para explorar sus secretos locales:
sottoDebes tener una identidad local desbloqueada antes de abrir el panel. Si hace falta, Sotto pide la
contraseña maestra. La entrada, la salida y la salida de error estándar deben estar conectadas a
terminales.
Si falta alguna, la CI está activa o TERM=dumb, la invocación sin subcomandos escribe la ayuda
en la salida de error estándar y termina con el código 2. Usa sotto --help para solicitar la
ayuda expresamente.
Usa las flechas o j y k para desplazarte. Pulsa / para buscar, ? para abrir la ayuda y Tab
para cambiar de entorno. Este cambio solo dura mientras el panel está abierto; sotto env use
cambia el entorno predeterminado del proyecto. Pulsa r para mostrar u ocultar el valor
seleccionado, c para copiarlo al portapapeles y q para salir. Esc cierra la búsqueda o el
diálogo actual; en la vista principal, borra una búsqueda activa o sale.
Pulsa t para recorrer los temas con vista previa en directo. Usa las flechas para ver cada tema
y pulsa Enter para guardar tu elección o Esc para cancelar. Las
reglas de precedencia de los temas explican cómo los ajustes del comando y del
entorno afectan a la preferencia guardada.
Ejecuta sotto status para ver si existe una identidad local, si la sesión está desbloqueada y
qué proyecto y entorno selecciona el directorio actual. Lee el estado local. No comprueba la
conexión con el servidor ni garantiza que todos los secretos guardados se puedan descifrar.
sotto status
sotto status --jsonUsa sotto status --json en scripts. initialized indica si existe una identidad local y
unlocked indica si hay una clave maestra en caché. project contiene name y environment
del sotto.toml más cercano, o es null fuera de un proyecto configurado. Un comando correcto
puede mostrar unlocked: false; los scripts que necesitan una sesión desbloqueada deben consultar ese campo.
Estos ejemplos JSON son ilustrativos. Con un sotto.toml pero sin identidad local:
{"initialized":false,"project":{"environment":"dev","name":"demo"},"unlocked":false}Sin un sotto.toml ni identidad local:
{"initialized":false,"project":null,"unlocked":false}Si falta sotto.toml, no hay ningún proyecto seleccionado. Un archivo mal formado o ilegible produce un error.
Para consultar el servidor configurado y la elegibilidad de tu cuenta para Cloud, inicia sesión primero:
sotto login
sotto cloud status
sotto cloud status --jsonEl comando necesita una sesión activa, pero no desbloquea el almacén local ni abre un navegador. Muestra el server configurado, el server_info del servidor, la eligibility de la cuenta y un billing_url solo cuando el estado devuelto indica que la facturación está disponible. La salida legible también muestra actions, next_actions y los valores opcionales paid_through_epoch, recovery_until_epoch o export_until_epoch. Si falta server_info o eligibility, significa que un servidor antiguo no expone ese endpoint; no demuestra que el acceso esté permitido o denegado.
El formato JSON es útil para scripts. Su estructura de nivel superior es:
{
"server": "https://getsotto.co.uk",
"billing_url": "https://getsotto.co.uk/cloud",
"server_info": {
"deployment_mode": "cloud",
"entitlement_model": "organisation_tiers_v1"
},
"eligibility": {
"model": "person_eligibility_v1",
"state": "paid",
"deployment_mode": "cloud",
"account_initialized": true,
"billing_available": true,
"paid_through_epoch": 1798761600,
"recovery_until_epoch": null,
"export_until_epoch": null,
"actions": {
"setup": false,
"billing": false,
"export": false,
"revoke": true
},
"next_actions": ["revoke"],
"payer": "personal"
}
}El ejemplo es sintético; actions y las fechas opcionales proceden del estado devuelto de la cuenta, y los servidores antiguos pueden devolver null para cualquiera de los dos endpoints. sotto cloud status solo informa del estado y puede mostrar una URL de facturación. No inicia una compra ni cambia la elegibilidad. Para diagnosticar el almacén local y los entornos, usa sotto status; esa vista es independiente de la información del servidor y de la cuenta anterior.
La CLI incluye cinco temas integrados: nord (el predeterminado), sordino, terminal,
monochrome y tokyo-night. Gestiónalos con sotto theme:
sotto theme ls # list available themes; the active one is marked
sotto theme set nord # save a preference for later commands
sotto theme current # print the theme this shell resolves to--theme <name> elige un tema para un solo comando. SOTTO_THEME lo fija para un shell y
sotto theme set lo guarda. La precedencia es --theme, luego SOTTO_THEME, luego la
preferencia guardada y por último nord; un nombre desconocido avisa por la salida de error
estándar y vuelve a nord.
El estilo solo se aplica en terminales interactivos. --plain, un NO_COLOR no vacío (el
contrato de no-color.org), los entornos de CI, la salida estándar en
una tubería y la entrada estándar redirigida suprimen cada uno el color y la decoración, pero
conservan la paleta elegida, así que los scripts y los registros se leen en texto plano.
Los temas personalizados son archivos TOML en el directorio themes dentro del directorio de
datos de tu plataforma: ~/Library/Application Support/sotto en macOS, %APPDATA%\sotto en
Windows y $XDG_DATA_HOME/sotto o ~/.local/share/sotto en Linux (SOTTO_DATA_DIR mueve ese
directorio). Cada archivo *.toml necesita los tokens de abajo y toma su nombre del campo
name, o del nombre del archivo cuando ese campo no está; un archivo que no se pueda
interpretar se omite. Los colores aceptan valores hexadecimales, nombres de colores ANSI,
índices ansi(<index>) y default.
bg = "#120024"
fg = "#ffffff"
accent = "#ff007f"
success = "#00ff66"
warning = "#ffaa00"
error = "#ff0033"
muted = "#775588"
border = "#331144"Guardado como synth.toml, ese archivo añade un tema synth. Aplícalo con
sotto theme set synth, o para un solo comando con sotto --theme synth <command>.
La CLI lee estas variables:
SOTTO_SERVER: la URL del servidor, que sustituye a la guardada porsotto login. ConSOTTO_TOKENes obligatoria salvo quesotto loginhaya guardado un servidor en esa máquina.SOTTO_TOKEN: un token de máquina.sotto runysotto exportleen entonces el entorno del token en lugar de la bóveda local.SOTTO_PASSWORD: la contraseña maestra, para scripts que no pueden responder a una solicitud. Siempre que puedas, usa la solicitud oculta.SOTTO_SECRET_KEY: la Secret Key de tu Emergency Kit, para ejecutarsotto setupsin solicitud.SOTTO_DATA_DIR: mueve el directorio de datos local, que contiene el almacén cifrado, los ajustes guardados (como el servidor) y los temas personalizados.SOTTO_THEMEyNO_COLOR: el estilo de la salida; consulta Temas de salida.
Un solo comando levanta un despliegue completo: Postgres, el servidor y Caddy con HTTPS
automático, desde deploy/docker-compose.prod.yml; el manual está en
deploy/README.md. Las piezas también funcionan por separado: sirve la app web y la API
desde un mismo origen (para que la cookie de sesión y la CSP sigan siendo del mismo origen); el
Caddyfile incluido sirve web/dist y actúa como proxy inverso de la API, con cabeceras de seguridad;
el Dockerfile construye la imagen del servidor (las migraciones se ejecutan al arrancar).
SOTTO_DEPLOYMENT_MODE vale self_hosted por defecto. En ese modo el servidor no aplica límites
de plan ni otras restricciones del servicio alojado, y no necesita una cuenta de Stripe. El modo
cloud es para el servicio que opera Sotto; lee el manual antes de activarlo.
Apunta la CLI a tu servidor una vez; los comandos posteriores lo reutilizan:
sotto login --server https://sotto.example.comCLI (native) ─────┐
├── sotto-core ── versioned encrypted data
Web client (WASM) ┘ │
▼
sync/API server
(ciphertext only)
El espacio de trabajo contiene cuatro crates:
crates/core: los tipos criptográficos compartidos y la implementación criptográfica completa.crates/cli: la interfaz de línea de comandossottoy el cliente nativo principal.crates/server: la API de sincronización basada en Axum.crates/wasm: enlaceswasm-bindgenque exponen el núcleo a los clientes web.
El cliente del navegador en web/ es una aplicación React y Vite que ejecuta el núcleo a través de crates/wasm.
- Rustup con Rust estable 1.89 o posterior
- Los componentes
clippyyrustfmt - El destino
wasm32-unknown-unknown - Para el cliente web: Node.js 22 (el que usa CI) y
wasm-pack(CI fija la v0.15.0) - Para el servidor y sus pruebas con base de datos: Postgres 16, que proporciona
docker compose up -d - Para las comprobaciones de scripts: Python 3.11 o posterior
El archivo rust-toolchain.toml incluido pide a Rustup que instale automáticamente los componentes y el
destino necesarios.
Clona el repositorio y luego compila y prueba el espacio de trabajo:
git clone https://github.com/getsotto/sotto.git
cd sotto
cargo build --workspace
cargo test --workspacecargo test --workspace no necesita base de datos, así que omite las pruebas de integración del
servidor y la prueba de extremo a extremo de la CLI sin fallar. Para ejecutarlas, inicia el Postgres
local y actívalas con SOTTO_RUN_DB_TESTS=1; rechazan un DATABASE_URL que apunte a cualquier
lugar que no sea esta máquina:
docker compose up -d
DATABASE_URL=postgres://sotto:sotto@localhost:5432/sotto SOTTO_RUN_DB_TESTS=1 \
cargo test -p sotto-server -p sotto-cliUsa la CLI en local (sin servidor):
cargo run -p sotto-cli -- --help
cargo run -p sotto-cli -- init # create an identity + project; prints your Emergency Kit
cargo run -p sotto-cli -- set DATABASE_URL # hidden prompt
cargo run -p sotto-cli -- run -- your-command # inject secrets as env vars into a subprocessLos secretos se cifran en reposo en un almacén SQLite local; la clave maestra se almacena en caché en el llavero del SO
con un TTL. Sincronizar con un servidor (login/push/pull/setup/share) es opcional.
El servidor necesita Postgres (un docker compose up -d lo levanta para uso local):
DATABASE_URL=postgres://sotto:sotto@localhost:5432/sotto cargo run -p sotto-server
curl http://127.0.0.1:8080/health # → okEl inicio de sesión con GitHub OAuth requiere GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET. Para cualquier despliegue no local
define también SOTTO_PUBLIC_URL con el origen del servidor accesible desde fuera (construye la
URL de callback de GitHub y debe coincidir con la registrada en la app OAuth; si no, se usa
http://localhost:8080) y, para el cliente web, SOTTO_WEB_ORIGIN. Sin OAuth el servidor
sigue arrancando (sirve /health y ejecuta las migraciones), pero el inicio de sesión y todos los endpoints autenticados
(sincronización, creación de enlaces para compartir) no están disponibles.
El cliente del navegador ejecuta el mismo núcleo criptográfico con WebAssembly (web/):
cd web
npm ci
npm run dev # dev server (proxies the API to localhost:8080)
npm run build # production bundle → web/dist (strict CSP + Subresource Integrity)
npm run typecheck # TypeScript checks; needs the WASM bindings a build generates
npm test # unit tests (Vitest)
npm run smoke # load the WASM core under Node and exercise itLa batería de pruebas del embudo con Playwright (npm run e2e) necesita una base de datos y una
compilación de producción previa; web/e2e/README.md explica la preparación.
Ejecuta las mismas comprobaciones básicas que usa CI:
cargo fmt --all --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspaceLa política de cadena de suministro se define en deny.toml y se comprueba en CI con
cargo-deny:
cargo deny checkEl job supply-chain de CI audita todo el lockfile con scripts/check-cargo-audit. La
guía de auditoría del lockfile explica la versión fijada de cargo-audit, las
pruebas de la política y las reglas de las excepciones inactivas del lockfile.
El control cruzado entre implementaciones demuestra que las compilaciones nativa y WASM coinciden: el texto cifrado producido en nativo se descifra byte a byte en WASM a partir de vectores de referencia compartidos:
wasm-pack test --node crates/wasmLa compilación web, su auditoría de dependencias y la comprobación de las traducciones del README
(scripts/check-readme-i18n) también se ejecutan en CI (.github/workflows/ci.yml).
CONTRIBUTING.md enlaza las guías de fuzzing, pruebas Kani, cobertura y
comprobaciones de garantía.
El servidor envía un ping anónimo al día (en los primeros 10-20 minutos tras el arranque) a
https://getsotto.co.uk/telemetry/v1/ping, para contar instancias activas y ver qué
versiones están en uso. La respuesta nombra la última versión, y el servidor registra una línea cuando
ejecuta una versión desactualizada. Esta es la carga útil completa: el código de envío está en
crates/server/src/telemetry.rs, y una prueba unitaria fija
la carga útil en exactamente estos cuatro campos:
{ "instance_id": "0d0972a6-…", "version": "0.2.0", "os": "linux", "arch": "x86_64" }instance_id es un UUID aleatorio generado una vez y guardado en tu base de datos, sin derivarse de nada,
así que no identifica hardware, equipo ni cuenta; eliminarlo convierte la instancia en un contador anónimo
nuevo. El lado de ingesta no guarda direcciones IP ni ubicación derivada. No hay conteos de organizaciones, miembros
ni secretos, ni eventos de uso. La CLI, el cliente web y WASM nunca envían nada.
Desactívalo con SOTTO_TELEMETRY=off (o la variable común a varias herramientas
DO_NOT_TRACK=1): cuando está desactivado la tarea nunca se inicia y
nunca se hace ninguna petición. SOTTO_TELEMETRY_URL redirige el ping (por ejemplo, para agregar una flota privada),
y los registros que llevan 12 meses inactivos se purgan del censo alojado.
El modelo de Sotto es de conocimiento cero: los secretos en texto plano y las claves de descifrado utilizables permanecen en los dispositivos cliente, y el servidor solo ve texto cifrado más metadatos mínimos. Esto está implementado pero aún no auditado de forma independiente: consulta SECURITY.md para el modelo, la exposición honesta de metadatos, cómo se refuerza la superficie web (que se vuelve a descargar en cada visita y es, por tanto, más débil) y cómo verificar las versiones firmadas. El modelo de adversario completo, las garantías y los no objetivos explícitos están publicados en THREAT-MODEL.md. Reporta vulnerabilidades en privado según SECURITY.md.
El alcance y las pruebas preparados para una auditoría independiente están en SECURITY-AUDIT-SCOPE.md.
Sotto es Apache-2.0 y acepta contribuciones. Empieza en CONTRIBUTING.md; los good first issues están etiquetados, y las preguntas que no sean errores pertenecen a Discussions.
Reporta vulnerabilidades en privado según SECURITY.md.
Licenciado bajo la Licencia Apache, versión 2.0: todos los crates y el cliente web. No puedes usar este proyecto salvo conforme a la Licencia. Salvo que la ley aplicable lo exija o se acuerde por escrito, el software distribuido bajo la Licencia se distribuye «TAL CUAL», SIN GARANTÍAS NI CONDICIONES DE NINGÚN TIPO.