Kubernetes Secret Base64 Tool
Encode and decode Secret values with the YAML wrapper handled and the newline trap defused — entirely on this device.
No values yet — paste a Secret manifest above.
Scrollable table of decoded values. Use the arrow keys to scroll.
Base64 is encoding, not encryption — anyone who can read the manifest can read the values.
Press ? for shortcuts · Not stored — nothing leaves this device. This page keeps no copy of any value, ever.
This page loads no third-party code — no ads, no trackers, no analytics. Verify in your Network tab.
Do it offline:$ printf '%s' 'admin' | base64
How to use it
- Add key/value entries in Encode mode. The manifest updates as you type, with values written under data: as Base64 or under stringData: as plain text.
- Pick a Secret type (Opaque, kubernetes.io/dockerconfigjson or kubernetes.io/tls) and a DNS-1123 name. For the same literals the emitted manifest is byte-identical to kubectl create secret generic --dry-run=client -o yaml — proven against kubectl v1.36.1.
- Switch to Decode and paste a Secret manifest. Every data: value is decoded and masked; reveal rows one at a time, and Copy works without revealing anything on screen.
- Read the chips: a value whose last byte is a newline is the echo trap, named per row with the printf '%s' fix spelled out.
Paste key/value pairs and get a ready-to-apply Secret manifest with every value Base64-encoded — or paste a Secret from kubectl and read what is inside it. Decoded values stay masked until you reveal a row, trailing-newline traps are flagged per value, binary payloads render as hex instead of mojibake, and nothing you type or paste ever leaves this device — the page keeps no copy at all.
Examples
adminYWRtaW4=The username literal from the kubectl documentation's own example. printf '%s' 'admin' | base64, node's Buffer, kubectl create secret and this page all print YWRtaW4= — four independent encoders in agreement, five bytes in, eight characters out.
admin
YWRtaW4KThe same value with an invisible trailing newline — exactly what echo 'admin' | base64 produces, because echo appends one. Six bytes instead of five, a different string, and a login that fails at 2 a.m. The encoder flags the row; printf '%s' or echo -n avoids it.
apiVersion: v1
data:
password: czNjcjN0LVBhNTU=
username: YWRtaW4=
kind: Secret
metadata:
name: db-cred
password → s3cr3t-Pa55 · username → adminA kubectl-emitted Secret decoded: two clean UTF-8 rows, no warnings. This exact manifest is the executed kubectl v1.36.1 dry-run golden the page is tested against.
apiVersion: v1
kind: Secret
metadata:
name: blob-demo
data:
blob: AAECAw==
00010203AAECAw== decodes to four bytes that are not text. The row is labeled binary and shows a hex preview plus the byte count instead of garbled characters; Copy hands you the original Base64.
Every example on this page is executed against the same engine that powers the tool, on every build.
Gotchas worth knowing
The echo trap, mechanically
echo appends a newline unless you pass -n, so echo 'admin' | base64 encodes six bytes, not five, and prints YWRtaW4K where printf '%s' 'admin' | base64 prints YWRtaW4=. Kubernetes stores the six-byte value without complaint; your application fails on the invisible character. Every decoded row ending in 0x0a is flagged here.
Wrapped Base64 decodes like the cluster reads it
kubectl and the API server decode with Go's encoding/base64, which ignores line breaks but rejects interior spaces and missing padding. This page applies the same rules, so a literal-block scalar with wrapped Base64 decodes here exactly when it decodes in the cluster.
stringData wins on conflict
A key present in both data: and stringData: is legal YAML; at admission the stringData value takes precedence and the merged result lands in data:. The decoder shows both rows, each labeled with its source, so the conflict is visible before the cluster resolves it silently.
Binary values are first-class
A Secret can carry any bytes — a keystore, a DER certificate, a random key. When decoded bytes are not valid UTF-8 the row switches to a labeled hex preview with the byte count, and Copy returns the original Base64, the only lossless text form.
The 64 KiB working cap
Kubernetes caps a whole Secret at 1 MiB; this page caps input at 64 KiB and refuses anything larger outright, printing the CLI line — it never truncates a paste.
Common errors
kind is "ConfigMap", not Secret — this tool decodes Secret manifests only.- The paste was a manifest, just not a Secret — a ConfigMap looks identical apart from kind: and its plain-text values. Nothing is guessed from shape: paste the Secret itself.
data.password is not valid Base64 — Invalid Base64: character ' ' at position 4- A plain-text value pasted under data:. Either encode it first — that is what Encode mode is for — or move it under stringData:, the field Kubernetes provides for exactly this.
data.username ends with a trailing newline — the classic `echo` trap. Build the value with printf '%s' or echo -n to drop it.- A warning, not a refusal: the value decodes fine, newline included. If the consumer is a password check or an API-key comparison, that newline is the bug you have been hunting.
FAQ
Is Base64 encryption?
No. Base64 is a reversible text encoding — base64 -d undoes it with no key — and the Kubernetes Secrets documentation carries the same warning: putting a value in a Secret does not make it confidential. Anyone who can read the manifest can read the values. For real protection combine RBAC with encryption at rest, or keep secrets out of manifests entirely with tools like Bitnami Sealed Secrets, Mozilla SOPS or age.
Why did my Secret value grow a trailing newline?
Almost always echo. echo 'value' | base64 encodes the newline echo appends, so the stored value is one byte longer than intended — YWRtaW4K instead of YWRtaW4= for admin. Rebuild the value with printf '%s' 'value' | base64 or echo -n; the decoder here flags every affected row.
What is the difference between data and stringData?
data: holds Base64-encoded values and is what the API server stores and returns. stringData: is a write-time convenience — plain text the server encodes and folds into data: at admission; it never appears when you read the Secret back. This page emits either field on Encode and labels stringData rows on Decode.
Keyboard shortcuts
- ⌘/Ctrl + Enter
- Re-run the active mode on its current input.
- ⌘/Ctrl + S
- Download the manifest as secret .yaml, not the web page.
- ⌘/Ctrl + C
- Copy the emitted Secret while nothing is selected.
- ⌘/Ctrl + Shift + C
- Force-copy the manifest over a live selection.
- s
- Switch between Encode and Decode (outside text fields).
- t
- Cycle the site theme (single-key, kill switch honored).
- ? or ⌘/Ctrl + /
- Open the shortcut list this page registers.
- Esc
- Close the dialog — input is never touched.