s g
s g

Reputation: 5647

Kubernetes / kubectl print all secrets

I would like to use kubectl to print out all key-value pairs in my Secrets. I cannot figure out how to do this in one line with the -o --jsonpath flag or by piping into jq. I could certainly make a script to do this but I feel there must be a better way, given that the kubernetes GUI is pretty straightforward and liberal when it comes to letting you view Secrets.

Say I create secret like so:

kubectl create secret generic testsecret --from-literal=key1=val1 --from-literal=key2=val2

Now I can run kubectl get secret testsecret -o json to get something like:

{
    "apiVersion": "v1",
    "data": {
        "key1": "dmFsMQ==",
        "key2": "dmFsMg=="
    },
    ...
}

I can do something like

kubectl get secret testsecret -o jsonpath='{.data}'

or

kubectl get secret testsecret -o json | jq '.data'

to get my key-value pairs in non-list format then I'd have to base64 --decode the values.

What is the easiest way to get a clean list of all my key-value pairs? Bonus points for doing this across all Secrets (as opposed to just one specific one, as I did here).

Upvotes: 26

Views: 39842

Answers (6)

jsxt
jsxt

Reputation: 1135

For my needs I wrote a shell function, a wrapper around jq, that allows me to filter by names and decode secrets. It doesn't depend on a kubectl version but requires jq in $PATH. It's quite simple in use:

divulge() {
    [ -t 0 ] && [ $# -eq 0 ] && {
        echo "\
Discover kubernetes secrets

Usage:
    kubectl get secrets [NAME] -o json | divulge [OPTIONS] [REGEXP]

Options:
  -g  Global search (find all matches, not just the first)
  -i  Case insensitive search
  -m  Multi line mode (. will match newlines)
  -n  Ignore empty matches
  -p  Both s and m modes are enabled
  -s  Single line mode (^ -> \A, $ -> \Z)
  -l  Find longest possible matches
  -x  Extended regex format (ignore whitespace and comments)

  -r  Output raw strings, not JSON texts; values are placed between [ and ]
      and marked with the prefix unsafe, if contain at least a whitespace
  -C  Colorize JSON
  -M  Monochrome JSON

Follow the below link to learn more about REGEXP:
https://jqlang.github.io/jq/manual/#Regularexpressions"
        return
    }

    unset DIVULGE_FLAGS DIVULGE_RAW DIVULGE_OPTS

    while getopts ':gimnpslxrCM' arg
    do
        case "$arg" in
        g | i | m | n | p | s | l | x )
            DIVULGE_FLAGS="$DIVULGE_FLAGS$arg" ;;
        r ) DIVULGE_RAW=1 ;;
        C | M ) DIVULGE_OPTS="$DIVULGE_OPTS -$arg" ;;
        * ) echo "Illegal option: -$OPTARG">&2 ; return 1 ;;
        esac
    done

    shift $(( OPTIND-1 ))

    # shellcheck disable=SC2086
    jq $DIVULGE_OPTS \
    --arg regex "$1" \
    --arg flags "$DIVULGE_FLAGS" \
    --arg raw "$DIVULGE_RAW" \
    -r '(.items?[]? // .)
| .data
| select(.)
| with_entries(
    select(
        .key
        | test($regex; $flags)
    )
    | .value |= @base64d
)
| (
    if $raw == ""
    then
        select(. != {})
    else
        to_entries
        | map(
            (
                if .value | test("\\s")
                then
                    "unsafe "
                else
                    "safe   "
                end
            ) + .key + " [" + .value + "]"
        )
        | .[]
    end
)'
}

A standalone version can be found by this link.

Upvotes: -1

Woody
Woody

Reputation: 11

Kubernetes get all secretes base64 decode them, and ignore null values.

# kubectl get secrets -A -o json | jq '.items[] |  \
select(null != .data) | {name: .metadata.name,data: .data|map_values(@base64d)}' \
> all_secrets_decoded.json

Upvotes: 1

Muthukumaran
Muthukumaran

Reputation: 187

When using the accepted answer you may come across exception

jq: error (at <stdin>:96): Cannot iterate over null (null)

This might be because some json might not be fully formed, use an additional filter

kubectl get secrets -o json | jq '.items[] |  select(null != .data) | {name: .metadata.name,data: .data|map_values(@base64d)}'

The above will ensure to produce expected results

Upvotes: 6

saranicole
saranicole

Reputation: 2453

I read this question as asking for how to decode all secrets in one go. I built on the accepted answer to produce a one-liner to do this:

kubectl get secrets -o json | jq '.items[] | {name: .metadata.name,data: .data|map_values(@base64d)}'

This has the added benefit of listing the name of the secret along with the decoded values for readability.

Upvotes: 26

Michele
Michele

Reputation: 113

If you need to extract tls certificates and/or keys from a kubernetes secret and you have an older jq version not supporting map_values(@base64d):

kubectl get secrets tls-cert -o json | jq '.data' | cut -d '"' -f 4 | tr -d '{}' | base64 --decode

Upvotes: 2

peak
peak

Reputation: 116790

Sufficiently recent versions of jq have a filter for decoding base64 but it can only be used if the value that was encoded is a valid JSON string.

Anyway, you could start by trying:

.data | map_values(@base64d)

Upvotes: 16

Related Questions