cas

package
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 29, 2026 License: Apache-2.0 Imports: 6 Imported by: 0

Documentation

Overview

Package cas is the customer-held content-addressed payload store (architecture Q34–Q38, D7): blobs live under a store directory named by the lowercase-hex SHA-256 of their raw plaintext bytes, so the commitment recorded in a receipt and the storage address are one value.

Salting is deliberately absent: the store is customer-side, so a salt would break third-party verification and dedup while defending against nobody; the residual low-entropy-digest re-identification risk is accepted and documented (Q36, Q38).

This package was lifted out of internal/oidclogin/cas.go in Week 3 so the MCP proxy and the login flow write into the same store with the same rules; oidclogin now delegates here and keeps its own error sentinels.

Index

Constants

This section is empty.

Variables

View Source
var ErrMissing = errors.New("cas: blob missing from store")

ErrMissing marks a blob that is not in the store — the customer deleted it, or never had it. Distinct from ErrTampered because a verifier must tell "deleted" apart from "altered" (Q22, Q36, D7).

View Source
var ErrTampered = errors.New("cas: blob content does not match its digest")

ErrTampered marks a blob whose bytes no longer hash to their name.

Functions

func Digest

func Digest(b []byte) string

Digest returns the lowercase-hex SHA-256 of b — the commitment and the store address in one value (Q36).

Types

type Store

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

Store is one content-addressed store rooted at a directory.

func New

func New(dir string) *Store

New returns a Store over dir without touching the filesystem.

func (*Store) Dir

func (s *Store) Dir() string

Dir returns the store's root directory.

func (*Store) Ensure

func (s *Store) Ensure() error

Ensure creates the store directory with owner-only permissions.

func (*Store) Get

func (s *Store) Get(digest string) ([]byte, error)

Get reads the blob for digest and re-verifies the content address. Returns ErrMissing (wrapped) if absent, ErrTampered (wrapped) if the bytes do not hash to digest.

func (*Store) Path

func (s *Store) Path(digest string) string

Path returns the store path for a digest.

func (*Store) Put

func (s *Store) Put(b []byte) (string, error)

Put writes b into the store and returns its digest. Blobs may carry identity material (the ID token) or tool arguments, so files are mode 0600. Writing an already-present digest is a no-op.

func (*Store) ReadRaw

func (s *Store) ReadRaw(digest string) ([]byte, error)

ReadRaw reads the blob for digest WITHOUT re-verifying the content address. It exists for exactly one job: characterising a blob that Get has already refused, so a reader can report what the altered bytes are rather than only that they are altered (Q83's `unreadable` state).

Callers must not serve these bytes as the payload. They are, by construction, not the bytes the receipt commits to — that is what Get just said — so treating them as the record would defeat the commitment. Use Get everywhere else.

type TamperError

type TamperError struct {
	Want string // the name the blob is stored under
	Got  string // what its current bytes hash to
}

TamperError is the concrete ErrTampered, carrying both digests so a caller can report what the content actually hashes to.

func (*TamperError) Error

func (e *TamperError) Error() string

func (*TamperError) Is

func (e *TamperError) Is(target error) bool

Is makes errors.Is(err, ErrTampered) true for a *TamperError.

Jump to

Keyboard shortcuts

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