npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@linode/kubeseal-encrypt

v1.0.1

Published

Hybrid RSA-OAEP + AES-GCM encryption for Kubernetes Sealed Secrets in browser and Node.js

Downloads

345

Readme

@linode/kubeseal-encrypt

Hybrid RSA-OAEP + AES-GCM encryption for Kubernetes Sealed Secrets, compatible with both browser and Node.js environments.

Features

  • ✅ Browser and Node.js support
  • ✅ Compatible with Bitnami Sealed Secrets
  • ✅ TypeScript with full type definitions
  • ✅ Zero runtime dependencies
  • ✅ ESM and CommonJS support
  • ✅ PEM validation
  • ✅ Tree-shakeable

Installation

npm install @linode/kubeseal-encrypt

Usage

Browser

import { encryptSecretItem } from '@linode/kubeseal-encrypt'

const publicKeyPEM = `-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA...
-----END PUBLIC KEY-----`

const encryptedData = await encryptSecretItem(
  publicKeyPEM,
  'default', // Kubernetes namespace
  'my-secret-value'
)

console.log(encryptedData)

Node.js

const { encryptSecretItem } = require('@linode/kubeseal-encrypt')
const fs = require('fs')

// Read PEM from file
const publicKeyPEM = fs.readFileSync('./sealed-secrets-cert.pem', 'utf8')

// Encrypt data
const encryptedData = await encryptSecretItem(
  publicKeyPEM,
  'default',
  'my-secret-value'
)

console.log(encryptedData)

With Validation

import { encryptSecretItem, validatePEM, validateNamespace } from '@linode/kubeseal-encrypt'

// Validate PEM before using
const pemValidation = validatePEM(publicKeyPEM)
if (!pemValidation.valid) {
  console.error('Invalid PEM:', pemValidation.error)
  process.exit(1)
}

// Validate namespace
const nsValidation = validateNamespace('my-namespace')
if (!nsValidation.valid) {
  console.error('Invalid namespace:', nsValidation.error)
  process.exit(1)
}

// Encrypt
const encrypted = await encryptSecretItem(publicKeyPEM, 'my-namespace', 'secret-value')

API Reference

encryptSecretItem(sealedSecretsPEM, namespace, data)

Encrypts data using the Sealed Secrets public key.

Parameters:

  • sealedSecretsPEM (string): PEM-formatted RSA public key from sealed-secrets controller
  • namespace (string): Kubernetes namespace (required)
  • data (string): Data to encrypt

Returns: Promise<string> - Encrypted data

Throws:

  • Error if PEM format is invalid
  • Error if namespace is invalid
  • Error if crypto API is unavailable

validatePEM(pem)

Validates PEM format.

Parameters:

  • pem (string): PEM-formatted public key

Returns: ValidationResult - Object with valid boolean and optional error message

validateNamespace(namespace)

Validates Kubernetes namespace format.

Parameters:

  • namespace (string): Kubernetes namespace to validate

Returns: ValidationResult - Object with valid boolean and optional error message

How It Works

This package implements the same hybrid encryption scheme as kubeseal:

  1. RSA-OAEP: Encrypts a random 256-bit AES session key using the sealed-secrets public key
  2. AES-GCM: Encrypts the actual data with the session key
  3. Output format: [2-byte RSA length][RSA-encrypted key][AES-encrypted data][16-byte auth tag]

The namespace is used as the RSA-OAEP label for additional security, ensuring that encrypted data can only be decrypted in the correct namespace.

Getting the Public Key

The recommended way to get the sealed-secrets public certificate is using kubeseal:

Method 1: Fetch from Controller (Recommended)

kubeseal --fetch-cert \
  --controller-name=sealed-secrets-controller \
  --controller-namespace=kube-system \
  > sealed-secrets-cert.pem

[!NOTE]
Replace sealed-secrets-controller and kube-system with your actual controller name and namespace if different.

This fetches the certificate directly from the sealed-secrets controller running in your cluster.

Method 2: Download from Kubernetes directly

The controller prints the certificate to its logs on startup. You can retrieve it with:

kubectl get secret -n kube-system sealed-secrets-key \
  -o jsonpath="{.data['public\.pem']}" | base64 -d > sealed-secrets-cert.pem

[!NOTE]
Replace the namespace and secret name if they are different in your setup.

Notes

  • The certificate automatically renews every 30 days (since v0.9.x)
  • For offline/air-gapped environments, save the certificate locally and distribute it
  • You can set the SEALED_SECRETS_CERT environment variable to point to a local certificate file

Requirements

  • Browser: Modern browser with Web Crypto API support
  • Node.js: Version 18.0.0 or higher

TypeScript

This package includes full TypeScript type definitions:

import type { ValidationResult, CryptoAdapter, AlgorithmConfig } from '@linode/kubeseal-encrypt'

Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Build package
npm run build

# Create local tarball for testing
npm run pack:local

Testing Locally

In Another Project

  1. Build and pack the package:

    npm run build
    npm pack
  2. Install in your project:

    npm install /path/to/linode-kubeseal-encrypt-1.0.0.tgz
  3. Use it:

    const { encryptSecretItem } = require('@linode/kubeseal-encrypt')

In Kubernetes Cluster

  1. Get the sealed-secrets public key:

    kubeseal --fetch-cert \
      --controller-name=sealed-secrets-controller \
      --controller-namespace=kube-system \
      > sealed-secrets-cert.pem

    [!NOTE]
    Replace sealed-secrets-controller and kube-system with your actual controller name and namespace if different.

  2. Create a test script:

    const { encryptSecretItem } = require('@linode/kubeseal-encrypt')
    const fs = require('fs')
    
    ;(async () => {
      const pem = fs.readFileSync('public-key.pem', 'utf8')
      const encrypted = await encryptSecretItem(pem, 'default', 'test-secret')
      console.log('Encrypted:', encrypted)
    })()
  3. Create a SealedSecret manifest:

    apiVersion: bitnami.com/v1alpha1
    kind: SealedSecret
    metadata:
      name: my-sealed-secret
      namespace: default
    spec:
      encryptedData:
        password: <encrypted-data-from-script>
  4. Apply and verify:

    kubectl apply -f sealed-secret.yaml
    kubectl get secret my-sealed-secret -o yaml

License

Copyright 2025 Akamai Technologies, Inc.

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

For security issues, please see SECURITY.md.

Privacy

For information about Akamai's privacy practices, please visit https://www.akamai.com/legal/privacy-statement