cfsign

package
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Jul 2, 2026 License: Apache-2.0 Imports: 18 Imported by: 0

Documentation

Overview

Package cfsign produces AWS CloudFront *canned-policy* signed URLs, and an origin.Origin that re-signs and fetches each request through them. It realizes the "S3 miss → CloudFront fallback (re-signed)" composition from examples/s3-cdn.Cadishfile: a `sign cloudfront …` upstream is wrapped so every outgoing request URL is signed with the CloudFront private key before the GET.

It is a stdlib reimplementation of the AWS SDK's feature/cloudfront/sign: a CloudFront canned-policy signature is an RSA-SHA1 (PKCS#1 v1.5) signature over a compact JSON policy, base64-encoded with CloudFront's URL-safe alphabet. Producing the same bytes the SDK does keeps it byte-for-byte CloudFront-compatible (proven by the sign↔verify round-trip in the test), with no extra dependency.

CloudFront binds a canned-policy signature to the resource URL's host, so the signature MUST be generated for the distribution domain (e.g. d111111abcdef8.cloudfront.net) — never an alias. The `to` URL of the signed upstream is that distribution; cadish signs for it and GETs it directly.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func EncodeKeyPath

func EncodeKeyPath(key string) string

EncodeKeyPath builds the CloudFront URL path for an object key. Every byte of it is load-bearing:

  • the '+'→'%2B' replacement keeps keys with '+' (e.g. phone-number usernames) from decoding to a space at the S3 origin (which 403s);
  • the key's OWN leading slash is preserved — a key "/feeds.csv" maps to the URL path "//feeds.csv" — so we prepend the URL's leading "/" without ever trimming the key's.

func LoadRSA

func LoadRSA(path string) (*rsa.PrivateKey, error)

LoadRSA parses an RSA private key PEM in PKCS#1 ("RSA PRIVATE KEY") or PKCS#8 ("PRIVATE KEY") form — the two encodings openssl and the AWS console emit, so the same CloudFront private PEMs load unchanged.

Types

type Origin

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

Origin is an origin.Origin that CloudFront-signs each request URL before fetching it. It wraps a Signer (the distribution + key) and a freshness window: every Fetch mints a canned-policy URL valid for ttl, then streams a plain HTTPS GET of that signed URL. It is the composable building block behind a `sign cloudfront …` upstream — just an origin.Origin, so it drops into an `origin chain` like any other backend.

The streaming / status contract mirrors httporigin exactly: 200/206 stream the live body (caller closes), 3xx pass through (we never follow — SSRF guard), 404 → origin.ErrNotFound, any other status → *origin.StatusError so a chain can fall through.

func NewOrigin

func NewOrigin(signer *Signer, ttl time.Duration, opts ...OriginOption) *Origin

NewOrigin builds a signing origin. ttl is the validity window minted into each signed URL (clamped to a small positive default when non-positive).

func (*Origin) Fetch

func (o *Origin) Fetch(ctx context.Context, in *origin.Request) (*origin.Response, error)

Fetch signs in.Key for the configured distribution and streams a GET of the signed URL.

type OriginOption

type OriginOption func(*Origin)

OriginOption configures an Origin.

func WithClock

func WithClock(now func() time.Time) OriginOption

WithClock overrides the clock used to compute the signed URL's expiry (tests).

func WithHTTPClient

func WithHTTPClient(hc *http.Client) OriginOption

WithHTTPClient overrides the internal http.Client (tests / advanced wiring). The client MUST NOT set a body-transfer timeout (it would truncate large streams) and SHOULD NOT follow redirects.

type Signer

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

Signer mints CloudFront canned-policy signed URLs for one distribution under one key-pair. It is immutable and safe for concurrent use.

func New

func New(base, keyPairID string, key *rsa.PrivateKey) (*Signer, error)

New builds a Signer for the distribution at base ("https://d111….cloudfront.net") signing under keyPairID with key. base must have a scheme and host.

func NewFromPEM

func NewFromPEM(base, keyPairID, pemPath string) (*Signer, error)

NewFromPEM is New with the private key loaded from a PEM file.

func (*Signer) KeyPairID

func (s *Signer) KeyPairID() string

KeyPairID returns the configured key-pair id (for diagnostics/tests).

func (*Signer) SignedURL

func (s *Signer) SignedURL(objKey string, expires time.Time) (string, error)

SignedURL returns a CloudFront canned-policy signed URL for objKey, valid until expires. The resource is "<base><EncodeKeyPath(objKey)>" and the returned URL appends the canned-policy query params (Expires, Signature, Key-Pair-Id).

Jump to

Keyboard shortcuts

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