meeko auth hash
Prompts for a password without echoing it, or reads it from stdin, and prints its scrypt hash for storage in .env or the database.
meeko auth hash hashes a password with hashPassword, the same hash checked by verifyPassword, without writing code. In a terminal it prompts twice without echoing; with a pipe, it reads stdin. Use it to create an initial administrator's or service account's password without leaving plaintext in shell history.
Only the hash goes to standard output, on one line: meeko auth hash >> .env or a pipe receives a clean line. Prompts and errors go to standard error.
Usage#
meeko auth hashContraseña:
Repite la contraseña:
scrypt$131072$8$1$5jmbLtw9yk7j9cKXvoj1Cw$MycUbPu8gwqzW2hpMac0eTDbEnanlwS4rw-uc4MbSiUType#
meeko auth hashParameters#
| Input | Type | Default | Description |
|---|---|---|---|
| Terminal (stdin is a TTY) | text, without echo | Prompts with Contraseña: and Repite la contraseña:. Backspace deletes; Ctrl+C, or Ctrl+D on an empty line, cancels. Control characters and escape sequences (arrows, bracketed paste) are ignored. |
|
| Pipe (stdin is not a TTY) | text | Reads all input and removes a single trailing newline (\n or \r\n). Must be a single line. |
The command accepts no options: meeko auth without hash produces Falta el subcomando de auth: meeko auth hash, and another subcommand produces Subcomando desconocido de auth: ….
Result#
A line scrypt$<N>$<r>$<p>$<sal>$<hash> on standard output and exit code 0. Parameters are the current hashPassword defaults: N = 2^17, r = 8 and p = 1, a random 16-byte salt and a 32-byte key, in base64url. Each run produces a different hash for the same password because of the salt.
| Error | Message | Code |
|---|---|---|
| The two inputs do not match | Las contraseñas no coinciden |
1 |
| Empty password in the terminal | La contraseña está vacía |
1 |
| Empty password through a pipe | La contraseña está vacía (through 1.6, The password is empty) |
1 |
| More than one line through a pipe | La entrada debe tener una sola línea con la contraseña |
1 |
| More than 4096 bytes | La contraseña supera 4096 bytes (through 1.6, The password exceeds 4096 bytes) |
1 |
| Canceled | Cancelado |
1 |
Examples#
Add it to .env#
printf 'ADMIN_PASSWORD_HASH=' >> .env
meeko auth hash >> .envPrompts still appear in the terminal because they go to standard error. The .env ends up with ADMIN_PASSWORD_HASH=scrypt$131072$8$1$…; Meeko reads it without expanding $.
From a variable, in CI or a script#
printf '%s' "$ADMIN_PASSWORD" | npx meeko auth hashIn PowerShell:
$env:ADMIN_PASSWORD | npx meeko auth hashprintf '%s' does not add a newline; echo does, and the command removes one, so both work.
Verify it at sign-in#
// server/api/login.post.ts
import { verifyPassword } from "@meekojs/meeko/password";
import { Login, LoginResult } from "../../shared/schemas";
export default defineApiRoute({
body: Login,
response: LoginResult,
origin: "required",
rateLimit: { limit: 5, window: "5m" },
async handler({ body, context }) {
const valid = await verifyPassword(body.password, process.env.ADMIN_PASSWORD_HASH ?? "");
if (!valid || body.username !== process.env.ADMIN_USERNAME) throw new ApiError("INVALID_CREDENTIALS", 401);
await context.session.create({ user: body.username });
return { ok: true };
},
});Common mistakes#
Paste the hash unquoted into the shell#
export ADMIN_PASSWORD_HASH=scrypt$131072$8$1$a60roveYGWNsSr73LMYxbw$eN20ddK5QyliDsTEoU5ah1SHPar1flUtYQd4J-a6dzIThe shell expands $1, $8 and the rest as variables: the variable becomes scrypt31072, and verifyPassword throws TypeError: Invalid password hash: expected scrypt$<N>$<r>$<p>$<salt>$<hash> within Meeko's limits. The same happens with $ in a docker-compose.yml, which also interpolates.
export ADMIN_PASSWORD_HASH='scrypt$131072$8$1$a60roveYGWNsSr73LMYxbw$eN20ddK5QyliDsTEoU5ah1SHPar1flUtYQd4J-a6dzI'In a Meeko .env, quotes are unnecessary: it does not expand variables.
Multiple lines through the pipe#
printf 'secreto\notra\n' | meeko auth hashLa entrada debe tener una sola línea con la contraseña. The command does not trim spaces or take the first line: whatever arrives is the password.
printf '%s' 'secreto' | meeko auth hashWrite the password as an argument#
meeko auth hash secretoArgumento de más para auth: secreto, with usage and exit code 1. An argument would remain in shell history and the process list; this is why it does not exist.
meeko auth hashNotes#
- Security. The password never goes to standard output or arguments. There is no terminal echo; with
printf '%s' "$VAR", the variable can remain in history if you type it literally on the command line. - Cost. Each hash uses 128 MiB during computation and takes a fraction of a second; this is expected for scrypt with these parameters.
- Supported environments. Runs in Node; the hash works in any runtime with
@meekojs/meeko/password(Node, Bun, Deno). Cloudflare Workers does not have enough memory to verify it. - Windows. In PowerShell,
$env:VAR | meeko auth hashsends the line with its newline, which the command removes (\nor\r\n). Incmd,echo secreto | meeko auth hashincludes the space before|in the password ("secreto "): writeecho secreto| meeko auth hash. - Rehashing. If defaults change in the future, old hashes remain valid;
needsRehash(hash)tells you when to recompute after a successful sign-in.