ssk

package module
v0.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2026 License: MIT Imports: 17 Imported by: 0

README

sops-sakura-kms

A SOPS wrapper that enables SOPS (Secrets OPerationS) to use Sakura Cloud KMS for data key encryption.

This tool acts as a Vault Transit Engine compatible HTTP server, allowing SOPS to encrypt and decrypt data keys using Sakura Cloud KMS through the SOPS_VAULT_URIS environment variable.

Features

  • SOPS Integration: Seamlessly integrates SOPS with Sakura Cloud KMS
  • Vault Compatibility: Implements Vault Transit Engine compatible API
  • Automatic Configuration: Automatically configures SOPS with the correct Vault Transit URI
  • Transparent Operation: Works as a wrapper around SOPS, passing through all SOPS commands
  • Server-Only Mode: Can run as a standalone Vault Transit Engine compatible server without SOPS

Installation

Homebrew
brew install fujiwara/tap/sops-sakura-kms
Binary releases

Download the latest binary from the releases page.

From source
go install github.com/fujiwara/sops-sakura-kms/cmd/sops-sakura-kms@latest
GitHub Action

You can install sops-sakura-kms in your GitHub Actions workflows.

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: fujiwara/sops-sakura-kms@main
        with:
          version: 'v0.0.7' # or 'latest'
          # version-file: './.version'

This action sets up sops-sakura-kms and makes it available in the PATH. The sops command needs to be installed separately.

Container Image

You can use the provided container image: ghcr.io/fujiwara/sops-sakura-kms.

$ docker run --rm \
    -e SAKURA_ACCESS_TOKEN \
    -e SAKURA_ACCESS_TOKEN_SECRET \
    -e SAKURA_KMS_KEY_ID \
    -v $(pwd):/work -w /work \
    ghcr.io/fujiwara/sops-sakura-kms:v0.0.7 \
    -d secrets.enc.yaml

This image includes both sops-sakura-kms and sops commands.

Prerequisites

  • SOPS must be installed and available in your PATH
  • Sakura Cloud API credentials must be set in environment variables

Configuration

Set the following environment variables:

# Sakura Cloud API credentials
export SAKURA_ACCESS_TOKEN="your-access-token"
export SAKURA_ACCESS_TOKEN_SECRET="your-access-token-secret"

# Sakura Cloud KMS Resource ID (12-digit number as string, e.g., 123456789012)
export SAKURA_KMS_KEY_ID="123456789012"

Note: For backward compatibility, the following alternative environment variable names are also supported. If both are set, SAKURA_* takes priority.

Primary (Recommended) Alternative
SAKURA_ACCESS_TOKEN SAKURACLOUD_ACCESS_TOKEN
SAKURA_ACCESS_TOKEN_SECRET SAKURACLOUD_ACCESS_TOKEN_SECRET
SAKURA_KMS_KEY_ID SAKURACLOUD_KMS_KEY_ID
Optional Environment Variables

You can customize the behavior with these optional environment variables:

# Run server-only mode without executing SOPS (default: false)
export SSK_SERVER_ONLY=true

# Server listen address (default: 127.0.0.1:8200)
export SSK_SERVER_ADDR="127.0.0.1:8200"

# Command to execute (default: sops)
export SSK_COMMAND="/path/to/sops"

Usage

Use sops-sakura-kms as a drop-in replacement for the sops command:

# Encrypt a file
sops-sakura-kms -e secrets.yaml > secrets.enc.yaml

# Decrypt a file
sops-sakura-kms -d secrets.enc.yaml

# Edit an encrypted file
sops-sakura-kms secrets.enc.yaml
How it works
  1. sops-sakura-kms starts a local Vault Transit Engine compatible HTTP server on 127.0.0.1:8200
  2. Automatically sets the SOPS_VAULT_URIS environment variable to http://127.0.0.1:8200/v1/transit/encrypt/{key_id}
  3. Sets required environment variables (VAULT_ADDR, VAULT_TOKEN)
  4. Executes SOPS with the configured environment
  5. The server handles encryption/decryption requests from SOPS using Sakura Cloud KMS
Exit Code

sops-sakura-kms preserves the exit code from the wrapped command (SOPS or custom command specified by SSK_COMMAND).

  • If the wrapped command exits with code N, sops-sakura-kms also exits with code N
  • If an error occurs before executing the wrapped command (e.g., missing environment variables, server startup failure), sops-sakura-kms exits with code 1
SOPS Configuration

You can use the standard SOPS configuration file (.sops.yaml) without specifying the hc_vault_transit_uri:

creation_rules:
  - path_regex: \.yaml$
    # No need to specify hc_vault_transit_uri - it's automatically configured via SOPS_VAULT_URIS

Note: The wrapper automatically sets the SOPS_VAULT_URIS environment variable, so you don't need to configure it manually in .sops.yaml or pass it as a command-line argument.

Server-Only Mode

You can run sops-sakura-kms as a standalone Vault Transit Engine compatible server without executing SOPS:

# Start server-only mode
export SSK_SERVER_ONLY=true
sops-sakura-kms

# The server will run until interrupted (Ctrl+C)

This mode is useful when:

  • You want to use the Vault Transit Engine API directly from your applications
  • You need to run the server as a separate service
  • You're testing or debugging the encryption/decryption API endpoints

In server-only mode, you can use the Vault API endpoints directly:

# Encrypt data
curl -X PUT http://127.0.0.1:8200/v1/transit/encrypt/123456789012 \
  -H "Content-Type: application/json" \
  -d '{"plaintext":"aGVsbG8gd29ybGQ="}'

# Decrypt data
curl -X PUT http://127.0.0.1:8200/v1/transit/decrypt/123456789012 \
  -H "Content-Type: application/json" \
  -d '{"ciphertext":"vault:v1:..."}'
Using with Terraform

You can use sops-sakura-kms to decrypt secrets in Terraform using the sops_file data source.

First, create an encrypted file with SOPS:

sops-sakura-kms -e secrets.yaml > secrets.enc.yaml

Then, use the encrypted file in Terraform:

# main.tf
terraform {
  required_providers {
    sops = {
      source  = "carlpett/sops"
      version = "~> 1.0"
    }
  }
}

data "sops_file" "secrets" {
  source_file = "secrets.enc.yaml"
}

output "secret_value" {
  value     = data.sops_file.secrets.data["password"]
  sensitive = true
}

Run Terraform with sops-sakura-kms:

# Set SSK_COMMAND to run terraform instead of sops
export SSK_COMMAND=terraform
sops-sakura-kms plan
sops-sakura-kms apply

The wrapper automatically starts the Vault Transit Engine compatible server, sets the required environment variables (VAULT_ADDR, VAULT_TOKEN, SOPS_VAULT_URIS), and executes Terraform. The sops provider will use the local server to decrypt secrets.

API Endpoints

The tool provides the following Vault Transit Engine compatible endpoints:

  • GET /health - Health check endpoint
  • PUT /v1/transit/encrypt/{key_id} - Encrypt data using specified KMS key
  • PUT /v1/transit/decrypt/{key_id} - Decrypt data using specified KMS key

Using as a Go Library

You can embed Sakura Cloud KMS-based SOPS decryption in your Go applications by combining RunServer with the SOPS decrypt package.

package main

import (
	"context"
	"encoding/json"
	"os"

	ssk "github.com/fujiwara/sops-sakura-kms"
	"github.com/getsops/sops/v3/decrypt"
)

type Config struct {
	DatabaseURL string `json:"database_url"`
	APIKey      string `json:"api_key"`
}

func main() {
	ctx := context.Background()

	// Start Vault Transit Engine compatible server
	addEnv, shutdown, err := ssk.RunServer(ctx, "127.0.0.1:8200", os.Getenv("SAKURA_KMS_KEY_ID"))
	if err != nil {
		panic(err)
	}
	defer shutdown(context.Background())

	// Set environment variables for SOPS library
	for k, v := range addEnv {
		os.Setenv(k, v)
	}

	// Decrypt SOPS-encrypted file
	plaintext, err := decrypt.File("secrets.enc.json", "json")
	if err != nil {
		panic(err)
	}

	var cfg Config
	if err := json.Unmarshal(plaintext, &cfg); err != nil {
		panic(err)
	}
	// Use cfg...
}
RunServer Function
func RunServer(ctx context.Context, addr, keyID string) (map[string]string, func(context.Context) error, error)

Parameters:

  • ctx: Context for server operations
  • addr: Server listen address (e.g., "127.0.0.1:8200")
  • keyID: Sakura Cloud KMS resource ID (12-digit number)

Returns:

  • map[string]string: Environment variables for SOPS (VAULT_ADDR, VAULT_TOKEN, SOPS_VAULT_URIS)
  • func(context.Context) error: Shutdown function to stop the server
  • error: Any error that occurred during startup

Note: Sakura Cloud API credentials (SAKURA_ACCESS_TOKEN, SAKURA_ACCESS_TOKEN_SECRET) must be set in environment variables before calling RunServer.

Development

Running Tests
# Run all tests
go test ./...

# Run tests with actual Sakura Cloud KMS (requires credentials and KEY_ID)
KEY_ID=123456789012 go test ./...
Building
make build

License

MIT License - see LICENSE file for details

Author

FUJIWARA Shunichiro

Documentation

Overview

Package ssk provides a Vault Transit Engine compatible API server that enables SOPS to use Sakura Cloud KMS for data key encryption.

Wrapper Mode

The primary use case is as a SOPS wrapper via the command-line tool. See the cmd/sops-sakura-kms package for the CLI entrypoint.

Library Usage

You can also use this package as a Go library to embed Sakura Cloud KMS-based SOPS decryption in your applications. Use RunServer to start the Vault Transit Engine compatible server, then use the SOPS decrypt package to decrypt files.

addEnv, shutdown, err := ssk.RunServer(ctx, "127.0.0.1:8200", keyID)
if err != nil {
    return err
}
defer shutdown(context.Background())

for k, v := range addEnv {
    os.Setenv(k, v)
}

plaintext, err := decrypt.File("secrets.enc.yaml", "yaml")

Environment Variables

The following environment variables must be set:

  • SAKURACLOUD_ACCESS_TOKEN: Sakura Cloud API access token
  • SAKURACLOUD_ACCESS_TOKEN_SECRET: Sakura Cloud API access token secret

For wrapper mode, also set:

  • SAKURACLOUD_KMS_KEY_ID: Sakura Cloud KMS resource ID (12-digit number)

Index

Constants

View Source
const (
	VaultPrefix    = "vault:v1:"
	KeyIDPathParam = "key_id"

	// ExitCodeError is the exit code returned when an error occurs in the application.
	ExitCodeError = 1
)

Variables

View Source
var Version = "v0.4.0"

Functions

func DecryptHandlerFunc

func DecryptHandlerFunc(cipher Cipher) func(w http.ResponseWriter, r *http.Request)

DecryptHandlerFunc returns an HTTP handler for Vault Transit Engine decrypt endpoint.

func EncryptHandlerFunc

func EncryptHandlerFunc(cipher Cipher) func(w http.ResponseWriter, r *http.Request)

EncryptHandlerFunc returns an HTTP handler for Vault Transit Engine encrypt endpoint.

func NewMux

func NewMux(cipher Cipher) *http.ServeMux

NewMux creates a new HTTP ServeMux with Vault Transit Engine compatible API endpoints.

func RunServer added in v0.3.0

func RunServer(ctx context.Context, addr, keyID string) (map[string]string, func(context.Context) error, error)

RunServer starts the Vault Transit Engine compatible API server using Sakura Cloud KMS. Returns environment variables to configure SOPS, a shutdown function, and any error that occurred.

func RunServerWithCipher added in v0.4.0

func RunServerWithCipher(ctx context.Context, addr, keyID string, cipher Cipher) (map[string]string, func(context.Context) error, error)

RunServerWithCipher starts the Vault Transit Engine compatible API server with the given Cipher. Returns environment variables to configure SOPS, a shutdown function, and any error that occurred.

func RunWrapper

func RunWrapper(ctx context.Context, args []string) (int, error)

RunWrapper starts a Vault Transit Engine compatible API server and executes a command. It automatically configures SOPS to use Sakura Cloud KMS via SOPS_VAULT_URIS environment variable. Requires SAKURA_KMS_KEY_ID environment variable to be set. Returns the exit code of the executed command and any error that occurred.

func ShowVersion added in v0.4.0

func ShowVersion(ctx context.Context, w io.Writer) (int, error)

Types

type Cipher

type Cipher interface {
	// Encrypt encrypts plaintext using the specified key ID.
	// Returns base64-encoded ciphertext string.
	Encrypt(ctx context.Context, keyID string, plaintext []byte) (string, error)
	// Decrypt decrypts ciphertext using the specified key ID.
	// Accepts base64-encoded ciphertext string and returns plaintext bytes.
	Decrypt(ctx context.Context, keyID string, ciphertext string) ([]byte, error)
}

Cipher defines the interface for encryption and decryption operations.

type Env added in v0.0.5

type Env struct {
	KMSKeyID   string `env:"SAKURA_KMS_KEY_ID,SAKURACLOUD_KMS_KEY_ID" required:""`
	ServerOnly bool   `env:"SSK_SERVER_ONLY" default:"false"`
	ServerAddr string `env:"SSK_SERVER_ADDR" default:"127.0.0.1:8200"`
	Command    string `env:"SSK_COMMAND" default:"sops"`
}

func LoadEnv added in v0.2.0

func LoadEnv() (*Env, error)

LoadEnv loads environment variables into an Env struct based on struct tags. It reads the "env" tag for the environment variable name, "default" tag for default values, and "required" tag for required fields.

type SakuraKMS

type SakuraKMS struct {
	// contains filtered or unexported fields
}

SakuraKMS implements Cipher interface using Sakura Cloud KMS.

func NewSakuraKMS

func NewSakuraKMS() (*SakuraKMS, error)

NewSakuraKMS creates a new SakuraKMS instance. It reads credentials from environment variables (SAKURACLOUD_ACCESS_TOKEN, SAKURACLOUD_ACCESS_TOKEN_SECRET).

func (*SakuraKMS) Decrypt

func (c *SakuraKMS) Decrypt(ctx context.Context, keyID string, ciphertext string) ([]byte, error)

Decrypt decrypts ciphertext using Sakura Cloud KMS.

func (*SakuraKMS) Encrypt

func (c *SakuraKMS) Encrypt(ctx context.Context, keyID string, plaintext []byte) (string, error)

Encrypt encrypts plaintext using Sakura Cloud KMS with AES-256-GCM algorithm.

type VaultDecryptRequest

type VaultDecryptRequest struct {
	Ciphertext string `json:"ciphertext"`
}

VaultDecryptRequest represents the request body for Vault Transit Engine decrypt API. Ciphertext must include "vault:v1:" prefix.

type VaultDecryptResponse

type VaultDecryptResponse struct {
	Plaintext string `json:"plaintext"`
}

VaultDecryptResponse represents the response body for Vault Transit Engine decrypt API. Plaintext is returned as base64-encoded string.

type VaultEncryptRequest

type VaultEncryptRequest struct {
	Plaintext string `json:"plaintext"`
}

VaultEncryptRequest represents the request body for Vault Transit Engine encrypt API. Plaintext must be base64-encoded string.

type VaultEncryptResponse

type VaultEncryptResponse struct {
	Ciphertext string `json:"ciphertext"`
}

VaultEncryptResponse represents the response body for Vault Transit Engine encrypt API. Ciphertext includes "vault:v1:" prefix followed by the encrypted data.

type VaultErrorResponse added in v0.0.3

type VaultErrorResponse struct {
	Errors []string `json:"errors"`
}

VaultErrorResponse represents the error response body for Vault API. Errors is an array of error message strings.

Directories

Path Synopsis
cmd
sops-sakura-kms command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL