encryptedstorage

package module
v0.0.0-...-2f3be07 Latest Latest
Warning

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

Go to latest
Published: Sep 23, 2025 License: MPL-2.0 Imports: 25 Imported by: 0

README

Caddy Encrypted Storage

The Caddy Encrypted Storage plugin is a storage plugin for Caddy that encrypts and decrypts files on the fly using SOPS.

Install

Like all other Caddy modules, you can build Caddy with this plugin using xcaddy:

xcaddy build --with github.com/mohammed90/caddy-encrypted-storage

Data Sample

The stored data is a JSON object. A run with the sample data in the module tests produces the following file stored in the backing storage:

{
	"data": "ENC[AES256_GCM,data:BbJmihdruQHuFGYx1B6hb0AL,iv:xpaItMxmt7ZEUzC5q2jugwyDsipfApTzFkm7zzyG3bI=,tag:53XIOqcvYx6hdW91Hynwhg==,type:str]",
	"sops": {
		"kms": null,
		"gcp_kms": null,
		"azure_kv": null,
		"hc_vault": null,
		"age": [
			{
				"recipient": "age1pjtsgtdh79nksq08ujpx8hrup0yrpn4sw3gxl4yyh0vuggjjp3ls7f42y2",
				"enc": "-----BEGIN AGE ENCRYPTED FILE-----\nYWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBkOEIzME1kNzhuaDVaRWh6\neTduK29lenZvNU9oejBLV2xkL2hOaVJ4Sml3CjY4NkVmT1h0bFE0ZXFiNmlPUTMz\nRXZNVVlhbEs0Um1ZM3BNbkx3WUZPam8KLS0tIEdIU295WGs2MmIvb0VPVCthZkwr\nN25aSi8yU3dsVlBxeHlnRkVLQlNjcWsKNaaOKatV+ncmpEYVuR4g40Njv8RIce+d\nMTV1koLrdXYFA5k0Xtjs/Xg9NocYFfs8aW2XgX8J3mSoy6lVKMwBsQ==\n-----END AGE ENCRYPTED FILE-----\n"
			}
		],
		"lastmodified": "2023-10-30T13:06:37Z",
		"mac": "ENC[AES256_GCM,data:kQLUguFnLQCT50fuHL7L3xeHoMTbC7JKLker1Y2S4prSZbu5QfJ5D44nd/ETpMMak/LFvRnhIEsBkeBNZxpcsTGkyMpAN8GG9C9+Cc2YAgPvm7Ubl+pQuPUp84ExXk7896l7zwWlY1XrITOiZ5PsZOiy1ZbMV+WEG6YQ5QWk4JY=,iv:+VnRSwOWupu1dlfeCG+aZU4yNuH0B2eVvkvHgXJbxTE=,tag:+lU43WSEp489EcV7RPhJ6w==,type:str]",
		"pgp": null,
		"version": ""
	}
}

Example

Caddyfile

Configuring the default storage module for Caddy in the Caddyfile is done using the storage global option.

{
	storage encrypted {
		backend file_system {
			root /var/caddy/storage
		}
		provider local {
			key age {
				recipient age1pjtsgtdh79nksq08ujpx8hrup0yrpn4sw3gxl4yyh0vuggjjp3ls7f42y2
				identity AGE-SECRET-KEY-16E6P6H93CXNPZQRJVNA5NMK4X06ZHCDU4ED9U89E3PZMASSMC46SX99PEWCDU4ED9U89E3PZMASSMC46SX99PEW
			}
		}
	}
}
https://example.com {
	respond "Howdy!"
}

The configuration accepts multiple identities whose values can be determined via environment variables.

{
	storage encrypted {
		backend file_system {
			root /var/caddy/storage
		}
		provider local {
			key age {
				recipient age1pjtsgtdh79nksq08ujpx8hrup0yrpn4sw3gxl4yyh0vuggjjp3ls7f42y2
				identity AGE-SECRET-KEY-16E6P6H93CXNPZQRJVNA5NMK4X06ZHCDU4ED9U89E3PZMASSMC46SX99PEWCDU4ED9U89E3PZMASSMC46SX99PEW
				identity {$AGE_SECRET_KEY}
			}
		}
	}
}
https://example.com {
	respond "Howdy!"
}

The configuration values can also be extracted via placeholders.

{
	storage encrypted {
		backend file_system {
			root /var/caddy/storage
		}
		provider local {
			key age {
				recipient {env.AGE_RECIPIENT}
				identity {env.AGE_SECRET}
			}
		}
	}
}
https://example.com {
	respond "Howdy!"
}
JSON

The simplest configuration of this module can be as follows:

{
	"storage": {
		"module": "encrypted",
		"backend": {
			"module": "file_system",
			"root": "/var/caddy/storage"
		},
		"encryption":[
			{
				"provider": "local",
				"keys": [
					{
						"type": "age",
						"recipient": "age1pjtsgtdh79nksq08ujpx8hrup0yrpn4sw3gxl4yyh0vuggjjp3ls7f42y2",
						"identities": ["AGE-SECRET-KEY-16E6P6H93CXNPZQRJVNA5NMK4X06ZHCDU4ED9U89E3PZMASSMC46SX99PEW"]
					}
				]
			}
		]
	}
	// ... rest of Caddy configuration
}

The module supports replaceable values (placeholders) where the actual values can be obtained from Caddy runtime or the environment. For instance, the earlier configuration can be changed to:

{
	"storage": {
		"module": "encrypted",
		"backend": {
			"module": "file_system",
			"root": "/var/caddy/storage"
		},
		"encryption":[
			{
				"provider": "local",
				"keys": [
					{
						"type": "age",
						"recipient": "age1pjtsgtdh79nksq08ujpx8hrup0yrpn4sw3gxl4yyh0vuggjjp3ls7f42y2",
						"identities": ["{env.AGE_IDENTITY_0}"]
					}
				]
			}
		]
	}
	// ... rest of Caddy configuration
}

Documentation

Overview

Much of the content of this file is copied from getsops/sops project at the following source with minor modifications: https://github.com/getsops/sops/blob/d7c2d7d30f1e3991c8646c1ad829a1c34263e05c/keyservice/server.go Per the terms of the MPL-2.0, the following applies: - The file (and the projct) retains the same license. - The file (and the project) retains the copyright notice. The source does not contain copyright notice, but the copyright of this code is assigned to original authors.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Age

type Age struct {
	// The public key generated by `age`
	Recipient string `json:"recipient,omitempty"`

	// The private keys generated by `age`
	Identities []string `json:"identities,omitempty"`
	// contains filtered or unexported fields
}

Age is a key type to be used with encryption provider. This key type uses age(age-encryption.org) key-pair for encryption/decryption. See more: [https://github.com/getsops/sops#encrypting-using-age](https://github.com/getsops/sops#encrypting-using-age)

func (Age) CaddyModule

func (a Age) CaddyModule() caddy.ModuleInfo

CaddyModule implements caddy.Module.

func (*Age) Provision

func (a *Age) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

func (*Age) ToMasterkey

func (a *Age) ToMasterkey() keys.MasterKey

ToMasterkey implements Masterkeyer.

func (*Age) UnmarshalCaddyfile

func (s *Age) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

type GCPKMS

type GCPKMS struct {
	// The subject resource ID as obtained from the GCP console.
	ResourceID string `json:"resource_id,omitempty"`

	// The raw JSON credentials as obtained from GCP
	Credentials json.RawMessage `json:"credentials,omitempty"`
	// contains filtered or unexported fields
}

GCPKMS uses GCPKMS (Google Cloud Platform KMS) for the encryption/decryption. See more: [https://github.com/getsops/sops#encrypting-using-gcp-kms](https://github.com/getsops/sops#encrypting-using-gcp-kms)

func (GCPKMS) CaddyModule

func (GCPKMS) CaddyModule() caddy.ModuleInfo

CaddyModule implements caddy.Module.

func (*GCPKMS) Provision

func (gcp *GCPKMS) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

func (*GCPKMS) ToMasterkey

func (gcp *GCPKMS) ToMasterkey() keys.MasterKey

ToMasterkey implements Masterkeyer.

func (*GCPKMS) UnmarshalCaddyfile

func (s *GCPKMS) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

type KeyGroupProvider

type KeyGroupProvider interface {
	KeyGroup() []sops.KeyGroup
}

KeyGroupProvider allows the `encrypted` storage module to obtain the keys from the encryption provider

type KeyServiceClientProvider

type KeyServiceClientProvider interface {
	KeyServiceClient() keyservice.KeyServiceClient
}

KeyServiceClientProvider allows the `encrypted` storage module to obtain the encryption/decryption client conforming to the provider.

type Local

type Local struct {
	// The encryption/decryption keyset
	Keys []json.RawMessage `json:"keys,omitempty" caddy:"namespace=caddy.storage.encrypted.key inline_key=type"`
	// contains filtered or unexported fields
}

Local encryption provider avails in-process encryption/decryption capabilities

func (Local) CaddyModule

func (Local) CaddyModule() caddy.ModuleInfo

CaddyModule implements caddy.Module.

func (Local) Decrypt

Decrypt takes a decrypt request and decrypts the provided ciphertext with the provided key, returning the decrypted result

func (*Local) Encrypt

Encrypt implements keyservice.KeyServiceServer.

func (*Local) KeyGroup

func (s *Local) KeyGroup() []sops.KeyGroup

KeyGroup implements KeyGroupGetter.

func (*Local) KeyServiceClient

func (l *Local) KeyServiceClient() keyservice.KeyServiceClient

KeyServiceClient implements KeyServiceClientProvider.

func (*Local) Provision

func (s *Local) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

func (*Local) UnmarshalCaddyfile

func (s *Local) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

type MasterkeyConverter

type MasterkeyConverter interface {
	ToMasterkey() keys.MasterKey
}

MasterkeyConverter allows conversion from the custom key type to SOPS `keys.MasterKey` interface type

type Remote

type Remote struct {
	Address string `json:"address,omitempty"`

	Keys []json.RawMessage `json:"keys,omitempty" caddy:"namespace=caddy.storage.encrypted.key inline_key=type"`
	// contains filtered or unexported fields
}

func (Remote) CaddyModule

func (Remote) CaddyModule() caddy.ModuleInfo

CaddyModule implements caddy.Module.

func (*Remote) Cleanup

func (r *Remote) Cleanup() error

Cleanup implements caddy.CleanerUpper.

func (*Remote) KeyGroup

func (r *Remote) KeyGroup() []sops.KeyGroup

KeyGroup implements KeyGroupGetter.

func (*Remote) KeyServiceClient

func (r *Remote) KeyServiceClient() keyservice.KeyServiceClient

KeyServiceClient implements KeyServiceClientProvider.

func (*Remote) Provision

func (r *Remote) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

type Storage

type Storage struct {
	// The backing storage where the encrypted data is stored.
	RawBackend json.RawMessage `json:"backend,omitempty" caddy:"namespace=caddy.storage inline_key=module"`

	// The encryption provider: local, remote. Although this is an array, current support is for 1 provider.
	// TODO: implemented the `remote` provider.
	// TODO: multiple providers
	Encryption []json.RawMessage `json:"encryption,omitempty" caddy:"namespace=caddy.storage.encrypted.provider inline_key=provider"`
	// contains filtered or unexported fields
}

Storage is the impelementation of certmagic.Storage interface for Caddy with encryption/decryption layer using [SOPS](https://github.com/getsops/sops). The module accepts any Caddy storage module as the backend.

func (Storage) CaddyModule

func (Storage) CaddyModule() caddy.ModuleInfo

CaddyModule implements caddy.Module.

func (*Storage) CertMagicStorage

func (s *Storage) CertMagicStorage() (certmagic.Storage, error)

CertMagicStorage implements caddy.StorageConverter.

func (*Storage) Delete

func (s *Storage) Delete(ctx context.Context, key string) error

Delete implements certmagic.Storage.

func (*Storage) Exists

func (s *Storage) Exists(ctx context.Context, key string) bool

Exists implements certmagic.Storage.

func (*Storage) List

func (s *Storage) List(ctx context.Context, path string, recursive bool) ([]string, error)

List implements certmagic.Storage.

func (*Storage) Load

func (s *Storage) Load(ctx context.Context, key string) ([]byte, error)

Load implements certmagic.Storage.

func (*Storage) Lock

func (s *Storage) Lock(ctx context.Context, name string) error

Lock implements certmagic.Storage.

func (*Storage) Provision

func (s *Storage) Provision(ctx caddy.Context) error

Provision implements caddy.Provisioner.

func (*Storage) Stat

func (s *Storage) Stat(ctx context.Context, key string) (certmagic.KeyInfo, error)

Stat implements certmagic.Storage.

func (*Storage) Store

func (s *Storage) Store(ctx context.Context, key string, value []byte) error

Store implements certmagic.Storage.

func (*Storage) Unlock

func (s *Storage) Unlock(ctx context.Context, name string) error

Unlock implements certmagic.Storage.

func (*Storage) UnmarshalCaddyfile

func (s *Storage) UnmarshalCaddyfile(d *caddyfile.Dispenser) error

Jump to

Keyboard shortcuts

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