Spec version: v0 (initial)
This document specifies the CLI interface for conforming Oboron implementations. Its purpose is to enable cross-implementation conformance testing via a shared CLI contract.
Conforming implementations provide two binaries:
ob
—
The primary CLI for secure encryption. Handles
a-tier schemes (aasv,
aags, apsv,
apgs) and the u-tier scheme
(upbc). All conforming
implementations MUST provide
ob.
obz
—
The obfuscation CLI for z-tier schemes
(zrbcx, legacy).
Implementations MAY choose not to support
z-tier; the obz binary is
OPTIONAL. If an implementation supports
z-tier, the obz binary MUST
conform to this specification.
The reference implementation source code is available at the GitHub repo
ob-enc/oboron-rs.
For cryptographic details, format definitions, and key management, see the protocol specification.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.
<REQUIRED> — a required argument or value[OPTIONAL] — an optional argument or value--flag — a long-form flag-f — a short-form flag--option <VALUE> — an option that takes a valueob
The ob binary is REQUIRED for all
conforming implementations. It handles a-tier and
u-tier encryption schemes.
obz
The obz binary is OPTIONAL. If
provided, it MUST conform to this specification.
It handles z-tier obfuscation schemes.
⚠️ Z-tier schemes are NOT cryptographically secure.
obzis for obfuscation only and MUST NOT be used for sensitive data.
| Aspect | ob |
obz |
|---|---|---|
| Key terminology | "key" (--key/-k,
86 base64 chars, 512-bit) |
"secret"
(--secret/-s,
43 base64 chars, 256-bit) |
| Config directory | ~/.ob/ |
~/.obz/ |
| Default scheme | aasv |
zrbcx |
| Default encoding | c32 |
c32 |
| Environment variable | OBORON_KEY |
OBORON_SECRET |
| Key output command | key
(alias: k) |
secret
(alias: s) |
The following commands MUST be implemented for a conforming CLI.
enc
(alias: e)Encrypt+encode a plaintext string.
ob enc [OPTIONS] [TEXT]
| Flag / Option | Short | Description |
|---|---|---|
--key
<KEY> |
-k |
Encryption key (86 base64 chars);
conflicts with
--profile/--keyless
|
--profile
<NAME> |
-p |
Use named key profile; conflicts with
--key/--keyless
|
--keyless |
-K |
Use hardcoded key (INSECURE —
testing only); conflicts with
--key/--profile
|
--format
<FORMAT> |
-f |
Format string (e.g.
aasv.b64); MUST NOT be
combined with scheme/encoding flags |
--aasv |
-s |
Use aasv scheme |
--apsv |
-S |
Use apsv scheme |
--aags |
-g |
Use aags scheme |
--apgs |
-G |
Use apgs scheme |
--upbc |
-u |
Use upbc scheme |
--c32 |
-c |
Use Crockford base32 encoding |
--b32 |
-b |
Use RFC base32 encoding |
--b64 |
-B |
Use base64 encoding |
--hex |
-x |
Use hex encoding |
--help |
-h |
Print help |
[TEXT] is omitted, the
implementation MUST read input from
stdin.--key,
--profile, and
--keyless are mutually
exclusive.--format MUST NOT be combined
with individual scheme or encoding
flags.\n),
exit 0.obz enc Variant
obz enc accepts the same flags with
these differences:
--secret/-s
instead of --key/-k.
Note: since obz has no a-tier
schemes, the -s short flag is
repurposed for --secret in
obz (it does not mean
--aasv).| Flag | Short | Description |
|---|---|---|
--zrbcx |
-r |
Use zrbcx scheme |
--legacy |
-l |
Use legacy scheme |
dec
(alias: d)Decode+decrypt an obtext string.
ob dec [OPTIONS] [TEXT]
| Flag / Option | Short | Description |
|---|---|---|
--key
<KEY> |
-k |
Encryption key (86 base64 chars);
conflicts with
--profile/--keyless
|
--profile
<NAME> |
-p |
Use named key profile; conflicts with
--key/--keyless
|
--keyless |
-K |
Use hardcoded key (INSECURE —
testing only); conflicts with
--key/--profile
|
--format
<FORMAT> |
-f |
Format string (e.g.
aasv.b64); MUST NOT be
combined with scheme/encoding flags |
--aasv |
-s |
Use aasv scheme |
--apsv |
-S |
Use apsv scheme |
--aags |
-g |
Use aags scheme |
--apgs |
-G |
Use apgs scheme |
--upbc |
-u |
Use upbc scheme |
--c32 |
-c |
Use Crockford base32 encoding |
--b32 |
-b |
Use RFC base32 encoding |
--b64 |
-B |
Use base64 encoding |
--hex |
-x |
Use hex encoding |
--help |
-h |
Print help |
[TEXT] is omitted, the
implementation MUST read input from
stdin.--key,
--profile, and
--keyless are mutually
exclusive.--format MUST NOT be combined
with individual scheme or encoding
flags.\n), exit 0.key /
secret
(alias: k /
s)
Output the encryption key (for ob)
or obfuscation secret (for obz) for
the active or specified profile.
ob key [OPTIONS]
obz secret [OPTIONS]
| Option | Short | Description |
|---|---|---|
--profile
<NAME> |
-p |
Use named key profile |
--keyless |
-K |
Output the hardcoded key |
--hex |
-x |
Output as hex instead of base64 |
--help |
-h |
Print help |
For obz, the command is
secret (alias: s), and
it outputs the 256-bit z-tier secret.
The following commands are RECOMMENDED but not required for conformance.
init
(alias: i)Initialize configuration with a randomly-generated key profile.
ob init [NAME]
[NAME] defaults to
default.
~/.ob/config.json and
~/.ob/profiles/<NAME>.json.
config.json structure:
{
"profile": "<NAME>",
"scheme": "aasv",
"encoding": "c32"
}{
"key": "<86-char base64 key>"
}~/.ob/bkp/).0o600
on Unix).For obz:
~/.obz/."secret"
instead of "key".zrbcx.{
"secret": "<43-char base64 secret>"
}config
(alias: c)Manage configuration.
ob config [OPTIONS] [SUBCOMMAND]
| Subcommand | Description |
|---|---|
show |
Print current configuration (default when no subcommand given) |
set |
Set configuration values |
config set
Accepts scheme flags, encoding flags, and
--profile <NAME> to update
the stored configuration.
profile
(alias: p)Manage key profiles.
ob profile <SUBCOMMAND>
| Subcommand | Aliases | Description |
|---|---|---|
list |
l |
List all key profiles |
show |
g, get |
Show a specific profile (defaults to active if name omitted) |
activate |
a, use |
Set a profile as the default |
create |
c |
Create a new profile;
--key/-k
optional (generates if omitted) |
delete |
d |
Delete a profile |
rename |
r, mv |
Rename a profile (takes
<OLD>
<NEW>) |
set |
— | Replace the key in an existing profile;
--key/-k
optional (generates if omitted) |
Profile name validation: only alphanumeric characters, hyphens, and underscores are permitted.
completionGenerate shell completion scripts.
ob completion <SHELL>
| Subcommand | Description |
|---|---|
bash |
Generate bash completion script |
zsh |
Generate zsh completion script |
fish |
Generate fish completion script |
powershell |
Generate PowerShell completion script |
When resolving which key (or secret) to use, implementations MUST apply the following precedence order (highest to lowest):
| Priority | Source |
|---|---|
| 1 | --key /
--secret CLI flag |
| 2 | $OBORON_KEY /
$OBORON_SECRET environment
variable |
| 3 | --profile <NAME>
→ profile file |
| 4 | Default profile from config file |
| 5 | Error |
If no key source is available, the implementation MUST exit with a non-zero exit code.
The --format flag accepts format
strings of the form
{scheme}.{encoding}.
ob: aasv,
aags, apsv,
apgs, upbcobz: zrbcx,
legacy| Identifier | Description |
|---|---|
c32 |
Crockford base32 (lowercase, avoids accidental obscenity words) |
b32 |
RFC 4648 base32 (uppercase alphanumeric) |
b64 |
URL-safe base64 (RFC 4648 §5, most compact) |
hex |
Hexadecimal (longest output, slightly faster) |
Implementations SHOULD support the named scheme
flags (e.g. --aasv) as the primary
interface; the --format flag provides
a combined shorthand.
For cross-implementation testing, both
ob and obz support a
hardcoded key via the
-K/--keyless flag.
Implementations MUST use these exact values to
ensure test vector compatibility.
ob Master KeyBase64 (86 chars, URL-safe, no padding):
OBKEYz0C6l8134WWtcxCGDEAYEaOi0ZUVaQVF06m6Wap9I7sS6RG3fyLeFh4lTVvRadaGrdBlFTdn3qoqV291Q
Hex (128 chars):
381284633d02ea5f35df8596b5cc4218310060468e8b465455a415174ea6e966a9f48eec4ba446ddfc8b78587895356f45a75a1ab7419454dd9f7aa8a95dbdd5
obz Z-tier SecretThe z-tier secret is the first 32 bytes of the master key, encoded as base64url without padding.
Base64 (43 chars, URL-safe, no padding):
OBKEYz0C6l8134WWtcxCGDEAYEaOi0ZUVaQVF06m6WY
Bytes (hex):
38 12 84 63 3d 02 ea 5f
35 df 85 96 b5 cc 42 18
31 00 60 46 8e 8b 46 54
55 a4 15 17 4e a6 e9 66
Test vectors are stored as JSONL (JSON Lines) files. Each line is a JSON object with the following fields:
{
"format": "aags.c32",
"plaintext": "hello",
"obtext": "..."
}
Optional fields: "description".
For legacy vectors, the first line MAY be a meta object carrying the scheme-specific secret:
{
"type": "meta",
"secret": "<43-char base64url secret>"
}
| Scheme type | Enc test | Dec test | Roundtrip |
|---|---|---|---|
Deterministic (aags,
aasv,
zrbcx) |
Exact match against vector obtext | Exact match against vector plaintext | N/A (exact enc match proves roundtrip) |
Probabilistic (apgs,
apsv,
upbc) |
N/A (output differs each run) | Exact match against vector plaintext | enc → dec → assert equals original plaintext |
| Exit code | Meaning |
|---|---|
| 0 | Success |
| Non-zero | Error (invalid input, missing key, decryption failure, etc.) |
The following error conditions MUST produce a non-zero exit code:
encdec--key
and --keyless together)enc output:
obtext string followed by a single newline
(\n) on stdout.dec output:
plaintext string followed by a single newline
(\n) on stdout.[TEXT] is omitted, the
implementation MUST read the full contents of
stdin as input. A trailing newline from stdin
SHOULD be stripped (to support
echo "text" | ob enc
patterns).