Add RFC specs for auth crypt and trust packages
This commit is contained in:
parent
60b713114b
commit
82fd4e5267
8 changed files with 1665 additions and 0 deletions
521
specs/auth/RFC.md
Normal file
521
specs/auth/RFC.md
Normal file
|
|
@ -0,0 +1,521 @@
|
||||||
|
# auth
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/auth`
|
||||||
|
|
||||||
|
**Files:** 4
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
### `Authenticator`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Authenticator struct {
|
||||||
|
medium io.Medium
|
||||||
|
store SessionStore
|
||||||
|
hardwareKey HardwareKey // optional hardware key (nil = software only)
|
||||||
|
challenges map[string]*Challenge // userID -> pending challenge
|
||||||
|
mu sync.RWMutex // protects challenges map only
|
||||||
|
challengeTTL time.Duration
|
||||||
|
sessionTTL time.Duration
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Authenticator manages PGP-based challenge-response authentication.
|
||||||
|
All user data and keys are persisted through an io.Medium, which may
|
||||||
|
be backed by disk, memory (MockMedium), or any other storage backend.
|
||||||
|
Sessions are persisted via a SessionStore (in-memory by default,
|
||||||
|
optionally SQLite-backed for crash recovery).
|
||||||
|
|
||||||
|
An optional HardwareKey can be provided via WithHardwareKey for
|
||||||
|
hardware-backed cryptographic operations (PKCS#11, YubiKey, etc.).
|
||||||
|
See auth/hardware.go for the interface definition and integration points.
|
||||||
|
Usage: create an Authenticator with New(...) and then call Register, Login, or CreateChallenge.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `CreateChallenge`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) CreateChallenge(userID string) (*Challenge, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
CreateChallenge generates a cryptographic challenge for the given user.
|
||||||
|
A random nonce is created and encrypted with the user's PGP public key.
|
||||||
|
The client must decrypt the nonce and sign it to prove key ownership.
|
||||||
|
Usage: call CreateChallenge(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `DeleteUser`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) DeleteUser(userID string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
DeleteUser removes a user and all associated keys from storage.
|
||||||
|
The "server" user is protected and cannot be deleted (mirroring the
|
||||||
|
original TypeScript implementation's safeguard).
|
||||||
|
Usage: call DeleteUser(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `IsRevoked`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) IsRevoked(userID string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
IsRevoked checks whether a user's key has been revoked by inspecting the
|
||||||
|
.rev file. Returns true only if the file contains valid revocation JSON
|
||||||
|
(not the legacy "REVOCATION_PLACEHOLDER" string).
|
||||||
|
Usage: call IsRevoked(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Login`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) Login(userID, password string) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Login performs password-based authentication as a convenience method.
|
||||||
|
It verifies the password against the stored hash and, on success,
|
||||||
|
creates a new session. This bypasses the PGP challenge-response flow.
|
||||||
|
|
||||||
|
Hash format detection:
|
||||||
|
- If a .hash file exists, its content starts with "$argon2id$" and is verified
|
||||||
|
using constant-time Argon2id comparison.
|
||||||
|
- Otherwise, falls back to legacy .lthn file with LTHN hash verification.
|
||||||
|
On successful legacy login, the password is re-hashed with Argon2id and
|
||||||
|
a .hash file is written (transparent migration).
|
||||||
|
|
||||||
|
Usage: call Login(...) for password-based flows when challenge-response is not required.
|
||||||
|
|
||||||
|
##### `ReadResponseFile`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) ReadResponseFile(userID, path string) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
ReadResponseFile reads a signed response from a file and validates it,
|
||||||
|
completing the air-gapped authentication flow. The file must contain the
|
||||||
|
raw PGP signature bytes (armored).
|
||||||
|
Usage: call ReadResponseFile(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `RefreshSession`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) RefreshSession(token string) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
RefreshSession extends the expiry of an existing valid session.
|
||||||
|
Usage: call RefreshSession(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Register`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) Register(username, password string) (*User, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Register creates a new user account. It hashes the username with LTHN to
|
||||||
|
produce a userID, generates a PGP keypair (protected by the given password),
|
||||||
|
and persists the public key, private key, revocation placeholder, password
|
||||||
|
hash (Argon2id), and encrypted metadata via the Medium.
|
||||||
|
Usage: call Register(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `RevokeKey`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) RevokeKey(userID, password, reason string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
RevokeKey marks a user's key as revoked. It verifies the password first,
|
||||||
|
writes a JSON revocation record to the .rev file (replacing the placeholder),
|
||||||
|
and invalidates all sessions for the user.
|
||||||
|
Usage: call RevokeKey(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `RevokeSession`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) RevokeSession(token string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
RevokeSession removes a session, invalidating the token immediately.
|
||||||
|
Usage: call RevokeSession(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `RotateKeyPair`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) RotateKeyPair(userID, oldPassword, newPassword string) (*User, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
RotateKeyPair generates a new PGP keypair for the given user, re-encrypts
|
||||||
|
their metadata with the new key, updates the password hash, and invalidates
|
||||||
|
all existing sessions. The caller must provide the current password
|
||||||
|
(oldPassword) to decrypt existing metadata and the new password (newPassword)
|
||||||
|
to protect the new keypair.
|
||||||
|
Usage: call RotateKeyPair(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `StartCleanup`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) StartCleanup(ctx context.Context, interval time.Duration)
|
||||||
|
```
|
||||||
|
|
||||||
|
StartCleanup runs a background goroutine that periodically removes expired
|
||||||
|
sessions from the store. It stops when the context is cancelled.
|
||||||
|
Usage: call StartCleanup(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `ValidateResponse`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) ValidateResponse(userID string, signedNonce []byte) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
ValidateResponse verifies a signed nonce from the client. The client must
|
||||||
|
have decrypted the challenge nonce and signed it with their private key.
|
||||||
|
On success, a new session is created and returned.
|
||||||
|
Usage: call ValidateResponse(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `ValidateSession`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) ValidateSession(token string) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
ValidateSession checks whether a token maps to a valid, non-expired session.
|
||||||
|
Usage: call ValidateSession(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `WriteChallengeFile`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (a *Authenticator) WriteChallengeFile(userID, path string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
WriteChallengeFile writes an encrypted challenge to a file for air-gapped
|
||||||
|
(courier) transport. The challenge is created and then its encrypted nonce
|
||||||
|
is written to the specified path on the Medium.
|
||||||
|
Usage: call WriteChallengeFile(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Challenge`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Challenge struct {
|
||||||
|
Nonce []byte `json:"nonce"`
|
||||||
|
Encrypted string `json:"encrypted"` // PGP-encrypted nonce (armored)
|
||||||
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Challenge is a PGP-encrypted nonce sent to a client during authentication.
|
||||||
|
Usage: use Challenge with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `HardwareKey`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type HardwareKey interface {
|
||||||
|
// Sign produces a cryptographic signature over the given data using the
|
||||||
|
// hardware-stored private key. The signature format depends on the
|
||||||
|
// underlying device (e.g. ECDSA, RSA-PSS, EdDSA).
|
||||||
|
Sign(data []byte) ([]byte, error)
|
||||||
|
|
||||||
|
// Decrypt decrypts ciphertext using the hardware-stored private key.
|
||||||
|
// The ciphertext format must match what the device expects (e.g. RSA-OAEP).
|
||||||
|
Decrypt(ciphertext []byte) ([]byte, error)
|
||||||
|
|
||||||
|
// GetPublicKey returns the PEM or armored public key corresponding to the
|
||||||
|
// hardware-stored private key.
|
||||||
|
GetPublicKey() (string, error)
|
||||||
|
|
||||||
|
// IsAvailable reports whether the hardware key device is currently
|
||||||
|
// connected and operational. Callers should check this before attempting
|
||||||
|
// Sign or Decrypt to provide graceful fallback behaviour.
|
||||||
|
IsAvailable() bool
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
HardwareKey defines the contract for hardware-backed cryptographic operations.
|
||||||
|
Implementations should wrap PKCS#11 tokens, YubiKeys, TPM modules, or
|
||||||
|
similar tamper-resistant devices.
|
||||||
|
|
||||||
|
All methods must be safe for concurrent use.
|
||||||
|
Usage: implement HardwareKey and pass it to WithHardwareKey(...) to wire hardware-backed auth into New(...).
|
||||||
|
|
||||||
|
|
||||||
|
### `MemorySessionStore`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type MemorySessionStore struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
sessions map[string]*Session
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
MemorySessionStore is an in-memory SessionStore backed by a map.
|
||||||
|
Usage: use MemorySessionStore with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `Cleanup`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (m *MemorySessionStore) Cleanup() (int, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Cleanup removes all expired sessions and returns the count removed.
|
||||||
|
Usage: call Cleanup(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Delete`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (m *MemorySessionStore) Delete(token string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete removes a session by token.
|
||||||
|
Usage: call Delete(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `DeleteByUser`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (m *MemorySessionStore) DeleteByUser(userID string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
DeleteByUser removes all sessions belonging to the given user.
|
||||||
|
Usage: call DeleteByUser(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Get`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (m *MemorySessionStore) Get(token string) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Get retrieves a session by token.
|
||||||
|
Usage: call Get(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Set`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (m *MemorySessionStore) Set(session *Session) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Set stores a session, keyed by its token.
|
||||||
|
Usage: call Set(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Option`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Option func(*Authenticator)
|
||||||
|
```
|
||||||
|
|
||||||
|
Option configures an Authenticator.
|
||||||
|
Usage: use Option with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `Revocation`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Revocation struct {
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
RevokedAt time.Time `json:"revoked_at"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Revocation records the details of a revoked user key.
|
||||||
|
Stored as JSON in the user's .rev file, replacing the legacy placeholder.
|
||||||
|
Usage: use Revocation with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `SQLiteSessionStore`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SQLiteSessionStore struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
store *store.Store
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
SQLiteSessionStore is a SessionStore backed by core/store (SQLite KV).
|
||||||
|
A mutex serialises all operations because SQLite is single-writer.
|
||||||
|
Usage: use SQLiteSessionStore with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `Cleanup`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *SQLiteSessionStore) Cleanup() (int, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Cleanup removes all expired sessions and returns the count removed.
|
||||||
|
Usage: call Cleanup(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Close`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *SQLiteSessionStore) Close() error
|
||||||
|
```
|
||||||
|
|
||||||
|
Close closes the underlying SQLite store.
|
||||||
|
Usage: call Close(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Delete`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *SQLiteSessionStore) Delete(token string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Delete removes a session by token from SQLite.
|
||||||
|
Usage: call Delete(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `DeleteByUser`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *SQLiteSessionStore) DeleteByUser(userID string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
DeleteByUser removes all sessions belonging to the given user.
|
||||||
|
Usage: call DeleteByUser(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Get`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *SQLiteSessionStore) Get(token string) (*Session, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Get retrieves a session by token from SQLite.
|
||||||
|
Usage: call Get(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Set`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *SQLiteSessionStore) Set(session *Session) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Set stores a session in SQLite, keyed by its token.
|
||||||
|
Usage: call Set(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Session`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Session struct {
|
||||||
|
Token string `json:"token"`
|
||||||
|
UserID string `json:"user_id"`
|
||||||
|
ExpiresAt time.Time `json:"expires_at"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Session represents an authenticated session.
|
||||||
|
Usage: use Session with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `SessionStore`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type SessionStore interface {
|
||||||
|
Get(token string) (*Session, error)
|
||||||
|
Set(session *Session) error
|
||||||
|
Delete(token string) error
|
||||||
|
DeleteByUser(userID string) error
|
||||||
|
Cleanup() (int, error) // Remove expired sessions, return count removed
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
SessionStore abstracts session persistence.
|
||||||
|
Usage: use SessionStore with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `User`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type User struct {
|
||||||
|
PublicKey string `json:"public_key"`
|
||||||
|
KeyID string `json:"key_id"`
|
||||||
|
Fingerprint string `json:"fingerprint"`
|
||||||
|
PasswordHash string `json:"password_hash"` // Argon2id (new) or LTHN (legacy)
|
||||||
|
Created time.Time `json:"created"`
|
||||||
|
LastLogin time.Time `json:"last_login"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
User represents a registered user with PGP credentials.
|
||||||
|
Usage: use User with the other exported helpers in this package.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `New`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func New(m io.Medium, opts ...Option) *Authenticator
|
||||||
|
```
|
||||||
|
|
||||||
|
New creates an Authenticator that persists user data via the given Medium.
|
||||||
|
By default, sessions are stored in memory. Use WithSessionStore to provide
|
||||||
|
a persistent implementation (e.g. SQLiteSessionStore).
|
||||||
|
Usage: call New(...) to create a ready-to-use value.
|
||||||
|
|
||||||
|
|
||||||
|
### `NewMemorySessionStore`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewMemorySessionStore() *MemorySessionStore
|
||||||
|
```
|
||||||
|
|
||||||
|
NewMemorySessionStore creates a new in-memory session store.
|
||||||
|
Usage: call NewMemorySessionStore(...) to create a ready-to-use value.
|
||||||
|
|
||||||
|
|
||||||
|
### `NewSQLiteSessionStore`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewSQLiteSessionStore(dbPath string) (*SQLiteSessionStore, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
NewSQLiteSessionStore creates a new SQLite-backed session store.
|
||||||
|
Use ":memory:" for testing or a file path for persistent storage.
|
||||||
|
Usage: call NewSQLiteSessionStore(...) to create a ready-to-use value.
|
||||||
|
|
||||||
|
|
||||||
|
### `WithChallengeTTL`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WithChallengeTTL(d time.Duration) Option
|
||||||
|
```
|
||||||
|
|
||||||
|
WithChallengeTTL sets the lifetime of a challenge before it expires.
|
||||||
|
Usage: pass WithChallengeTTL(...) into the related constructor to adjust the default behaviour.
|
||||||
|
|
||||||
|
|
||||||
|
### `WithHardwareKey`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WithHardwareKey(hk HardwareKey) Option
|
||||||
|
```
|
||||||
|
|
||||||
|
WithHardwareKey configures the Authenticator to use a hardware key for
|
||||||
|
cryptographic operations where supported. When set, the Authenticator may
|
||||||
|
delegate signing, decryption, and public key retrieval to the hardware
|
||||||
|
device instead of using software PGP keys.
|
||||||
|
|
||||||
|
This is a forward-looking option — integration points are documented in
|
||||||
|
auth.go but not yet wired up.
|
||||||
|
Usage: pass WithHardwareKey(...) into New(...) to enable a HardwareKey implementation.
|
||||||
|
|
||||||
|
|
||||||
|
### `WithSessionStore`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WithSessionStore(s SessionStore) Option
|
||||||
|
```
|
||||||
|
|
||||||
|
WithSessionStore sets the SessionStore implementation.
|
||||||
|
If not provided, an in-memory store is used (sessions lost on restart).
|
||||||
|
Usage: pass WithSessionStore(...) into the related constructor to adjust the default behaviour.
|
||||||
|
|
||||||
|
|
||||||
|
### `WithSessionTTL`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func WithSessionTTL(d time.Duration) Option
|
||||||
|
```
|
||||||
|
|
||||||
|
WithSessionTTL sets the lifetime of a session before it expires.
|
||||||
|
Usage: pass WithSessionTTL(...) into the related constructor to adjust the default behaviour.
|
||||||
250
specs/crypt/RFC.md
Normal file
250
specs/crypt/RFC.md
Normal file
|
|
@ -0,0 +1,250 @@
|
||||||
|
# crypt
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/crypt`
|
||||||
|
|
||||||
|
**Files:** 6
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `AESGCMDecrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AESGCMDecrypt(ciphertext, key []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
AESGCMDecrypt decrypts ciphertext encrypted with AESGCMEncrypt.
|
||||||
|
The key must be 32 bytes. Expects the nonce prepended to the ciphertext.
|
||||||
|
Usage: call AESGCMDecrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `AESGCMEncrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func AESGCMEncrypt(plaintext, key []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
AESGCMEncrypt encrypts plaintext using AES-256-GCM.
|
||||||
|
The key must be 32 bytes. The nonce is randomly generated and prepended
|
||||||
|
to the ciphertext.
|
||||||
|
Usage: call AESGCMEncrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `ChaCha20Decrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ChaCha20Decrypt(ciphertext, key []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
ChaCha20Decrypt decrypts ciphertext encrypted with ChaCha20Encrypt.
|
||||||
|
The key must be 32 bytes. Expects the nonce prepended to the ciphertext.
|
||||||
|
Usage: call ChaCha20Decrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `ChaCha20Encrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func ChaCha20Encrypt(plaintext, key []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
ChaCha20Encrypt encrypts plaintext using ChaCha20-Poly1305.
|
||||||
|
The key must be 32 bytes. The nonce is randomly generated and prepended
|
||||||
|
to the ciphertext.
|
||||||
|
Usage: call ChaCha20Encrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Decrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Decrypt(ciphertext, passphrase []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Decrypt decrypts data encrypted with Encrypt.
|
||||||
|
Expects format: salt (16 bytes) + nonce (24 bytes) + ciphertext.
|
||||||
|
Usage: call Decrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `DecryptAES`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DecryptAES(ciphertext, passphrase []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
DecryptAES decrypts data encrypted with EncryptAES.
|
||||||
|
Expects format: salt (16 bytes) + nonce (12 bytes) + ciphertext.
|
||||||
|
Usage: call DecryptAES(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `DeriveKey`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DeriveKey(passphrase, salt []byte, keyLen uint32) []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
DeriveKey derives a key from a passphrase using Argon2id with default parameters.
|
||||||
|
The salt must be argon2SaltLen bytes. keyLen specifies the desired key length.
|
||||||
|
Usage: call DeriveKey(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `DeriveKeyScrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func DeriveKeyScrypt(passphrase, salt []byte, keyLen int) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
DeriveKeyScrypt derives a key from a passphrase using scrypt.
|
||||||
|
Uses recommended parameters: N=32768, r=8, p=1.
|
||||||
|
Usage: call DeriveKeyScrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Encrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Encrypt(plaintext, passphrase []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Encrypt encrypts data with a passphrase using ChaCha20-Poly1305.
|
||||||
|
A random salt is generated and prepended to the output.
|
||||||
|
Format: salt (16 bytes) + nonce (24 bytes) + ciphertext.
|
||||||
|
Usage: call Encrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `EncryptAES`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func EncryptAES(plaintext, passphrase []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
EncryptAES encrypts data using AES-256-GCM with a passphrase.
|
||||||
|
A random salt is generated and prepended to the output.
|
||||||
|
Format: salt (16 bytes) + nonce (12 bytes) + ciphertext.
|
||||||
|
Usage: call EncryptAES(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `HKDF`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HKDF(secret, salt, info []byte, keyLen int) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
HKDF derives a key using HKDF-SHA256.
|
||||||
|
secret is the input keying material, salt is optional (can be nil),
|
||||||
|
info is optional context, and keyLen is the desired output length.
|
||||||
|
Usage: call HKDF(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `HMACSHA256`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HMACSHA256(message, key []byte) []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
HMACSHA256 computes the HMAC-SHA256 of a message using the given key.
|
||||||
|
Usage: call HMACSHA256(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `HMACSHA512`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HMACSHA512(message, key []byte) []byte
|
||||||
|
```
|
||||||
|
|
||||||
|
HMACSHA512 computes the HMAC-SHA512 of a message using the given key.
|
||||||
|
Usage: call HMACSHA512(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `HashBcrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HashBcrypt(password string, cost int) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
HashBcrypt hashes a password using bcrypt with the given cost.
|
||||||
|
Cost must be between bcrypt.MinCost and bcrypt.MaxCost.
|
||||||
|
Usage: call HashBcrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `HashPassword`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func HashPassword(password string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
HashPassword hashes a password using Argon2id with default parameters.
|
||||||
|
Returns a string in the format: $argon2id$v=19$m=65536,t=3,p=4$<base64salt>$<base64hash>
|
||||||
|
Usage: call HashPassword(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `SHA256File`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func SHA256File(path string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
SHA256File computes the SHA-256 checksum of a file and returns it as a hex string.
|
||||||
|
Usage: call SHA256File(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `SHA256Sum`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func SHA256Sum(data []byte) string
|
||||||
|
```
|
||||||
|
|
||||||
|
SHA256Sum computes the SHA-256 checksum of data and returns it as a hex string.
|
||||||
|
Usage: call SHA256Sum(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `SHA512File`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func SHA512File(path string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
SHA512File computes the SHA-512 checksum of a file and returns it as a hex string.
|
||||||
|
Usage: call SHA512File(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `SHA512Sum`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func SHA512Sum(data []byte) string
|
||||||
|
```
|
||||||
|
|
||||||
|
SHA512Sum computes the SHA-512 checksum of data and returns it as a hex string.
|
||||||
|
Usage: call SHA512Sum(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `VerifyBcrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func VerifyBcrypt(password, hash string) (bool, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
VerifyBcrypt verifies a password against a bcrypt hash.
|
||||||
|
Usage: call VerifyBcrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `VerifyHMAC`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func VerifyHMAC(message, key, mac []byte, hashFunc func() hash.Hash) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
VerifyHMAC verifies an HMAC using constant-time comparison.
|
||||||
|
hashFunc should be sha256.New, sha512.New, etc.
|
||||||
|
Usage: call VerifyHMAC(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `VerifyPassword`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func VerifyPassword(password, hash string) (bool, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
VerifyPassword verifies a password against an Argon2id hash string.
|
||||||
|
The hash must be in the format produced by HashPassword.
|
||||||
|
Usage: call VerifyPassword(...) during the package's normal workflow.
|
||||||
30
specs/crypt/chachapoly/RFC.md
Normal file
30
specs/crypt/chachapoly/RFC.md
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
# chachapoly
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/crypt/chachapoly`
|
||||||
|
|
||||||
|
**Files:** 1
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `Decrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Decrypt(ciphertext []byte, key []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Decrypt decrypts data using ChaCha20-Poly1305.
|
||||||
|
Usage: call Decrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Encrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Encrypt(plaintext []byte, key []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Encrypt encrypts data using ChaCha20-Poly1305.
|
||||||
|
Usage: call Encrypt(...) during the package's normal workflow.
|
||||||
63
specs/crypt/lthn/RFC.md
Normal file
63
specs/crypt/lthn/RFC.md
Normal file
|
|
@ -0,0 +1,63 @@
|
||||||
|
# lthn
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/crypt/lthn`
|
||||||
|
|
||||||
|
**Files:** 1
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `GetKeyMap`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func GetKeyMap() map[rune]rune
|
||||||
|
```
|
||||||
|
|
||||||
|
GetKeyMap returns the current character substitution map.
|
||||||
|
Usage: call GetKeyMap(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Hash`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Hash(input string) string
|
||||||
|
```
|
||||||
|
|
||||||
|
Hash computes the LTHN hash of the input string.
|
||||||
|
|
||||||
|
The algorithm:
|
||||||
|
1. Derive a quasi-salt by reversing the input and applying character substitutions
|
||||||
|
2. Concatenate: input + salt
|
||||||
|
3. Compute SHA-256 of the concatenated string
|
||||||
|
4. Return the hex-encoded digest (64 characters, lowercase)
|
||||||
|
|
||||||
|
The same input always produces the same hash, enabling verification
|
||||||
|
without storing a separate salt value.
|
||||||
|
Usage: call Hash(...) when you need a deterministic content-style digest rather than a password hash.
|
||||||
|
|
||||||
|
|
||||||
|
### `SetKeyMap`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func SetKeyMap(newKeyMap map[rune]rune)
|
||||||
|
```
|
||||||
|
|
||||||
|
SetKeyMap replaces the default character substitution map.
|
||||||
|
Use this to customize the quasi-salt derivation for specific applications.
|
||||||
|
Changes affect all subsequent Hash and Verify calls.
|
||||||
|
Usage: call SetKeyMap(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Verify`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Verify(input string, hash string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify checks if an input string produces the given hash.
|
||||||
|
Returns true if Hash(input) equals the provided hash value.
|
||||||
|
Uses constant-time comparison to prevent timing attacks.
|
||||||
|
Usage: call Verify(...) during the package's normal workflow.
|
||||||
69
specs/crypt/openpgp/RFC.md
Normal file
69
specs/crypt/openpgp/RFC.md
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
# openpgp
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/crypt/openpgp`
|
||||||
|
|
||||||
|
**Files:** 1
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
### `Service`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Service struct {
|
||||||
|
core *framework.Core
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Service provides OpenPGP cryptographic operations.
|
||||||
|
Usage: use Service with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `CreateKeyPair`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) CreateKeyPair(name, passphrase string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
CreateKeyPair generates a new RSA-4096 PGP keypair.
|
||||||
|
Returns the armored private key string.
|
||||||
|
Usage: call CreateKeyPair(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `DecryptPGP`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) DecryptPGP(privateKey, message, passphrase string, opts ...any) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
DecryptPGP decrypts a PGP message using the provided armored private key and passphrase.
|
||||||
|
Usage: call DecryptPGP(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `EncryptPGP`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) EncryptPGP(writer goio.Writer, recipientPath, data string, opts ...any) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
EncryptPGP encrypts data for a recipient identified by their public key (armored string in recipientPath).
|
||||||
|
The encrypted data is written to the provided writer and also returned as an armored string.
|
||||||
|
Usage: call EncryptPGP(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `HandleIPCEvents`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) HandleIPCEvents(c *framework.Core, msg framework.Message) error
|
||||||
|
```
|
||||||
|
|
||||||
|
HandleIPCEvents handles PGP-related IPC messages.
|
||||||
|
Usage: call HandleIPCEvents(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `New`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func New(c *framework.Core) (any, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
New creates a new OpenPGP service instance.
|
||||||
|
Usage: call New(...) to create a ready-to-use value.
|
||||||
77
specs/crypt/pgp/RFC.md
Normal file
77
specs/crypt/pgp/RFC.md
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
# pgp
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/crypt/pgp`
|
||||||
|
|
||||||
|
**Files:** 1
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
### `KeyPair`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type KeyPair struct {
|
||||||
|
PublicKey string
|
||||||
|
PrivateKey string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
KeyPair holds armored PGP public and private keys.
|
||||||
|
Usage: use KeyPair with the other exported helpers in this package.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `CreateKeyPair`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func CreateKeyPair(name, email, password string) (*KeyPair, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
CreateKeyPair generates a new PGP key pair for the given identity.
|
||||||
|
If password is non-empty, the private key is encrypted with it.
|
||||||
|
Returns a KeyPair with armored public and private keys.
|
||||||
|
Usage: call CreateKeyPair(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Decrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Decrypt(data []byte, privateKeyArmor, password string) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Decrypt decrypts armored PGP data using the given armored private key.
|
||||||
|
If the private key is encrypted, the password is used to decrypt it first.
|
||||||
|
Usage: call Decrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Encrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Encrypt(data []byte, publicKeyArmor string) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Encrypt encrypts data for the recipient identified by their armored public key.
|
||||||
|
Returns the encrypted data as armored PGP output.
|
||||||
|
Usage: call Encrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Sign`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Sign(data []byte, privateKeyArmor, password string) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Sign creates an armored detached signature for the given data using
|
||||||
|
the armored private key. If the key is encrypted, the password is used
|
||||||
|
to decrypt it first.
|
||||||
|
Usage: call Sign(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Verify`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func Verify(data, signature []byte, publicKeyArmor string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Verify verifies an armored detached signature against the given data
|
||||||
|
and armored public key. Returns nil if the signature is valid.
|
||||||
|
Usage: call Verify(...) during the package's normal workflow.
|
||||||
56
specs/crypt/rsa/RFC.md
Normal file
56
specs/crypt/rsa/RFC.md
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
# rsa
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/crypt/rsa`
|
||||||
|
|
||||||
|
**Files:** 1
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
### `Service`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Service struct{}
|
||||||
|
```
|
||||||
|
|
||||||
|
Service provides RSA functionality.
|
||||||
|
Usage: use Service with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `Decrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) Decrypt(privateKey, ciphertext, label []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Decrypt decrypts data with a private key.
|
||||||
|
Usage: call Decrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Encrypt`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) Encrypt(publicKey, data, label []byte) ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Encrypt encrypts data with a public key.
|
||||||
|
Usage: call Encrypt(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `GenerateKeyPair`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s *Service) GenerateKeyPair(bits int) (publicKey, privateKey []byte, err error)
|
||||||
|
```
|
||||||
|
|
||||||
|
GenerateKeyPair creates a new RSA key pair.
|
||||||
|
Usage: call GenerateKeyPair(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `NewService`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewService() *Service
|
||||||
|
```
|
||||||
|
|
||||||
|
NewService creates and returns a new Service instance for performing RSA-related operations.
|
||||||
|
Usage: call NewService(...) to create a ready-to-use value.
|
||||||
599
specs/trust/RFC.md
Normal file
599
specs/trust/RFC.md
Normal file
|
|
@ -0,0 +1,599 @@
|
||||||
|
# trust
|
||||||
|
|
||||||
|
**Import:** `dappco.re/go/core/crypt/trust`
|
||||||
|
|
||||||
|
**Files:** 5
|
||||||
|
|
||||||
|
## Types
|
||||||
|
|
||||||
|
### `Agent`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Agent struct {
|
||||||
|
// Name is the unique identifier for the agent (e.g., "Athena", "Clotho").
|
||||||
|
Name string
|
||||||
|
// Tier is the agent's trust level.
|
||||||
|
Tier Tier
|
||||||
|
// ScopedRepos limits repo access for Tier 2 agents. Empty means no repo access.
|
||||||
|
// Tier 3 agents ignore this field (they have access to all repos).
|
||||||
|
ScopedRepos []string
|
||||||
|
// RateLimit is the maximum requests per minute. 0 means unlimited.
|
||||||
|
RateLimit int
|
||||||
|
// TokenExpiresAt is when the agent's token expires.
|
||||||
|
TokenExpiresAt time.Time
|
||||||
|
// CreatedAt is when the agent was registered.
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Agent represents an agent identity in the trust system.
|
||||||
|
Usage: use Agent with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `ApprovalQueue`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ApprovalQueue struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
requests map[string]*ApprovalRequest
|
||||||
|
nextID int
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
ApprovalQueue manages pending approval requests for NeedsApproval decisions.
|
||||||
|
Usage: use ApprovalQueue with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `Approve`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) Approve(id string, reviewedBy string, reason string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Approve marks a pending request as approved. Returns an error if the
|
||||||
|
request is not found or is not in pending status.
|
||||||
|
Usage: call Approve(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Deny`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) Deny(id string, reviewedBy string, reason string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Deny marks a pending request as denied. Returns an error if the
|
||||||
|
request is not found or is not in pending status.
|
||||||
|
Usage: call Deny(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Get`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) Get(id string) *ApprovalRequest
|
||||||
|
```
|
||||||
|
|
||||||
|
Get returns the approval request with the given ID, or nil if not found.
|
||||||
|
Usage: call Get(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Len`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
Len returns the total number of requests in the queue.
|
||||||
|
Usage: call Len(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Pending`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) Pending() []ApprovalRequest
|
||||||
|
```
|
||||||
|
|
||||||
|
Pending returns all requests with ApprovalPending status.
|
||||||
|
Usage: call Pending(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `PendingSeq`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) PendingSeq() iter.Seq[ApprovalRequest]
|
||||||
|
```
|
||||||
|
|
||||||
|
PendingSeq returns an iterator over all requests with ApprovalPending status.
|
||||||
|
Usage: call PendingSeq(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Submit`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (q *ApprovalQueue) Submit(agent string, cap Capability, repo string) (string, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
Submit creates a new approval request and returns its ID.
|
||||||
|
Returns an error if the agent name or capability is empty.
|
||||||
|
Usage: call Submit(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `ApprovalRequest`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ApprovalRequest struct {
|
||||||
|
// ID is the unique identifier for this request.
|
||||||
|
ID string
|
||||||
|
// Agent is the name of the requesting agent.
|
||||||
|
Agent string
|
||||||
|
// Cap is the capability being requested.
|
||||||
|
Cap Capability
|
||||||
|
// Repo is the optional repo context for repo-scoped capabilities.
|
||||||
|
Repo string
|
||||||
|
// Status is the current approval status.
|
||||||
|
Status ApprovalStatus
|
||||||
|
// Reason is a human-readable explanation from the reviewer.
|
||||||
|
Reason string
|
||||||
|
// RequestedAt is when the request was created.
|
||||||
|
RequestedAt time.Time
|
||||||
|
// ReviewedAt is when the request was reviewed (zero if pending).
|
||||||
|
ReviewedAt time.Time
|
||||||
|
// ReviewedBy is the name of the admin who reviewed the request.
|
||||||
|
ReviewedBy string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
ApprovalRequest represents a queued capability approval request.
|
||||||
|
Usage: use ApprovalRequest with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `ApprovalStatus`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type ApprovalStatus int
|
||||||
|
```
|
||||||
|
|
||||||
|
ApprovalStatus represents the state of an approval request.
|
||||||
|
Usage: use ApprovalStatus with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `String`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (s ApprovalStatus) String() string
|
||||||
|
```
|
||||||
|
|
||||||
|
String returns the human-readable name of the approval status.
|
||||||
|
Usage: call String(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `AuditEntry`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type AuditEntry struct {
|
||||||
|
// Timestamp is when the evaluation occurred.
|
||||||
|
Timestamp time.Time `json:"timestamp"`
|
||||||
|
// Agent is the name of the agent being evaluated.
|
||||||
|
Agent string `json:"agent"`
|
||||||
|
// Cap is the capability that was evaluated.
|
||||||
|
Cap Capability `json:"capability"`
|
||||||
|
// Repo is the repo context (empty if not repo-scoped).
|
||||||
|
Repo string `json:"repo,omitempty"`
|
||||||
|
// Decision is the evaluation outcome.
|
||||||
|
Decision Decision `json:"decision"`
|
||||||
|
// Reason is the human-readable reason for the decision.
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
AuditEntry records a single policy evaluation for compliance.
|
||||||
|
Usage: use AuditEntry with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `AuditLog`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type AuditLog struct {
|
||||||
|
mu sync.Mutex
|
||||||
|
entries []AuditEntry
|
||||||
|
writer io.Writer
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
AuditLog is an append-only log of policy evaluations.
|
||||||
|
Usage: use AuditLog with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `Entries`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *AuditLog) Entries() []AuditEntry
|
||||||
|
```
|
||||||
|
|
||||||
|
Entries returns a snapshot of all audit entries.
|
||||||
|
Usage: call Entries(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `EntriesFor`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *AuditLog) EntriesFor(agent string) []AuditEntry
|
||||||
|
```
|
||||||
|
|
||||||
|
EntriesFor returns all audit entries for a specific agent.
|
||||||
|
Usage: call EntriesFor(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `EntriesForSeq`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *AuditLog) EntriesForSeq(agent string) iter.Seq[AuditEntry]
|
||||||
|
```
|
||||||
|
|
||||||
|
EntriesForSeq returns an iterator over audit entries for a specific agent.
|
||||||
|
Usage: call EntriesForSeq(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `EntriesSeq`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *AuditLog) EntriesSeq() iter.Seq[AuditEntry]
|
||||||
|
```
|
||||||
|
|
||||||
|
EntriesSeq returns an iterator over all audit entries.
|
||||||
|
Usage: call EntriesSeq(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Len`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *AuditLog) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
Len returns the number of entries in the log.
|
||||||
|
Usage: call Len(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Record`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (l *AuditLog) Record(result EvalResult, repo string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Record appends an evaluation result to the audit log.
|
||||||
|
Usage: call Record(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Capability`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Capability string
|
||||||
|
```
|
||||||
|
|
||||||
|
Capability represents a specific action an agent can perform.
|
||||||
|
Usage: use Capability with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `Decision`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Decision int
|
||||||
|
```
|
||||||
|
|
||||||
|
Decision is the result of a policy evaluation.
|
||||||
|
Usage: use Decision with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `MarshalJSON`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (d Decision) MarshalJSON() ([]byte, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
MarshalJSON implements custom JSON encoding for Decision.
|
||||||
|
Usage: call MarshalJSON(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `String`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (d Decision) String() string
|
||||||
|
```
|
||||||
|
|
||||||
|
String returns the human-readable name of the decision.
|
||||||
|
Usage: call String(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `UnmarshalJSON`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (d *Decision) UnmarshalJSON(data []byte) error
|
||||||
|
```
|
||||||
|
|
||||||
|
UnmarshalJSON implements custom JSON decoding for Decision.
|
||||||
|
Usage: call UnmarshalJSON(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `EvalResult`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type EvalResult struct {
|
||||||
|
Decision Decision
|
||||||
|
Agent string
|
||||||
|
Cap Capability
|
||||||
|
Reason string
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
EvalResult contains the outcome of a capability evaluation.
|
||||||
|
Usage: use EvalResult with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `PoliciesConfig`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type PoliciesConfig struct {
|
||||||
|
Policies []PolicyConfig `json:"policies"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
PoliciesConfig is the top-level configuration containing all tier policies.
|
||||||
|
Usage: use PoliciesConfig with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `Policy`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Policy struct {
|
||||||
|
// Tier is the trust level this policy applies to.
|
||||||
|
Tier Tier
|
||||||
|
// Allowed lists the capabilities granted at this tier.
|
||||||
|
Allowed []Capability
|
||||||
|
// RequiresApproval lists capabilities that need human/higher-tier approval.
|
||||||
|
RequiresApproval []Capability
|
||||||
|
// Denied lists explicitly denied capabilities.
|
||||||
|
Denied []Capability
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Policy defines the access rules for a given trust tier.
|
||||||
|
Usage: use Policy with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `PolicyConfig`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type PolicyConfig struct {
|
||||||
|
Tier int `json:"tier"`
|
||||||
|
Allowed []string `json:"allowed"`
|
||||||
|
RequiresApproval []string `json:"requires_approval,omitempty"`
|
||||||
|
Denied []string `json:"denied,omitempty"`
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
PolicyConfig is the JSON-serialisable representation of a trust policy.
|
||||||
|
Usage: use PolicyConfig with the other exported helpers in this package.
|
||||||
|
|
||||||
|
|
||||||
|
### `PolicyEngine`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type PolicyEngine struct {
|
||||||
|
registry *Registry
|
||||||
|
policies map[Tier]*Policy
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
PolicyEngine evaluates capability requests against registered policies.
|
||||||
|
Usage: use PolicyEngine with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `ApplyPolicies`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (pe *PolicyEngine) ApplyPolicies(r io.Reader) error
|
||||||
|
```
|
||||||
|
|
||||||
|
ApplyPolicies loads policies from a reader and sets them on the engine,
|
||||||
|
replacing any existing policies for the same tiers.
|
||||||
|
Usage: call ApplyPolicies(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `ApplyPoliciesFromFile`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (pe *PolicyEngine) ApplyPoliciesFromFile(path string) error
|
||||||
|
```
|
||||||
|
|
||||||
|
ApplyPoliciesFromFile loads policies from a JSON file and sets them on the engine.
|
||||||
|
Usage: call ApplyPoliciesFromFile(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Evaluate`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (pe *PolicyEngine) Evaluate(agentName string, cap Capability, repo string) EvalResult
|
||||||
|
```
|
||||||
|
|
||||||
|
Evaluate checks whether the named agent can perform the given capability.
|
||||||
|
If the agent has scoped repos and the capability is repo-scoped, the repo
|
||||||
|
parameter is checked against the agent's allowed repos.
|
||||||
|
Usage: call Evaluate(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `ExportPolicies`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (pe *PolicyEngine) ExportPolicies(w io.Writer) error
|
||||||
|
```
|
||||||
|
|
||||||
|
ExportPolicies serialises the current policies as JSON to the given writer.
|
||||||
|
Usage: call ExportPolicies(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `GetPolicy`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (pe *PolicyEngine) GetPolicy(t Tier) *Policy
|
||||||
|
```
|
||||||
|
|
||||||
|
GetPolicy returns the policy for a tier, or nil if none is set.
|
||||||
|
Usage: call GetPolicy(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `SetPolicy`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (pe *PolicyEngine) SetPolicy(p Policy) error
|
||||||
|
```
|
||||||
|
|
||||||
|
SetPolicy replaces the policy for a given tier.
|
||||||
|
Usage: call SetPolicy(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Registry`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Registry struct {
|
||||||
|
mu sync.RWMutex
|
||||||
|
agents map[string]*Agent
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Registry manages agent identities and their trust tiers.
|
||||||
|
Usage: use Registry with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `Get`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Registry) Get(name string) *Agent
|
||||||
|
```
|
||||||
|
|
||||||
|
Get returns the agent with the given name, or nil if not found.
|
||||||
|
Usage: call Get(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Len`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Registry) Len() int
|
||||||
|
```
|
||||||
|
|
||||||
|
Len returns the number of registered agents.
|
||||||
|
Usage: call Len(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `List`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Registry) List() []Agent
|
||||||
|
```
|
||||||
|
|
||||||
|
List returns all registered agents. The returned slice is a snapshot.
|
||||||
|
Usage: call List(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `ListSeq`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Registry) ListSeq() iter.Seq[Agent]
|
||||||
|
```
|
||||||
|
|
||||||
|
ListSeq returns an iterator over all registered agents.
|
||||||
|
Usage: call ListSeq(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Register`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Registry) Register(agent Agent) error
|
||||||
|
```
|
||||||
|
|
||||||
|
Register adds or updates an agent in the registry.
|
||||||
|
Returns an error if the agent name is empty or the tier is invalid.
|
||||||
|
Usage: call Register(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Remove`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (r *Registry) Remove(name string) bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Remove deletes an agent from the registry.
|
||||||
|
Usage: call Remove(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `Tier`
|
||||||
|
|
||||||
|
```go
|
||||||
|
type Tier int
|
||||||
|
```
|
||||||
|
|
||||||
|
Tier represents an agent's trust level in the system.
|
||||||
|
Usage: use Tier with the other exported helpers in this package.
|
||||||
|
|
||||||
|
#### Methods
|
||||||
|
|
||||||
|
##### `String`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (t Tier) String() string
|
||||||
|
```
|
||||||
|
|
||||||
|
String returns the human-readable name of the tier.
|
||||||
|
Usage: call String(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
##### `Valid`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func (t Tier) Valid() bool
|
||||||
|
```
|
||||||
|
|
||||||
|
Valid returns true if the tier is a recognised trust level.
|
||||||
|
Usage: call Valid(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
## Functions
|
||||||
|
|
||||||
|
### `LoadPolicies`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LoadPolicies(r io.Reader) ([]Policy, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
LoadPolicies reads JSON from a reader and returns parsed policies.
|
||||||
|
Usage: call LoadPolicies(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `LoadPoliciesFromFile`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func LoadPoliciesFromFile(path string) ([]Policy, error)
|
||||||
|
```
|
||||||
|
|
||||||
|
LoadPoliciesFromFile reads a JSON file and returns parsed policies.
|
||||||
|
Usage: call LoadPoliciesFromFile(...) during the package's normal workflow.
|
||||||
|
|
||||||
|
|
||||||
|
### `NewApprovalQueue`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewApprovalQueue() *ApprovalQueue
|
||||||
|
```
|
||||||
|
|
||||||
|
NewApprovalQueue creates an empty approval queue.
|
||||||
|
Usage: call NewApprovalQueue(...) to create a ready-to-use value.
|
||||||
|
|
||||||
|
|
||||||
|
### `NewAuditLog`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewAuditLog(w io.Writer) *AuditLog
|
||||||
|
```
|
||||||
|
|
||||||
|
NewAuditLog creates an in-memory audit log. If a writer is provided,
|
||||||
|
each entry is also written as a JSON line to that writer (append-only).
|
||||||
|
Usage: call NewAuditLog(...) to create a ready-to-use value.
|
||||||
|
|
||||||
|
|
||||||
|
### `NewPolicyEngine`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewPolicyEngine(registry *Registry) *PolicyEngine
|
||||||
|
```
|
||||||
|
|
||||||
|
NewPolicyEngine creates a policy engine with the given registry and default policies.
|
||||||
|
Usage: call NewPolicyEngine(...) to create a ready-to-use value.
|
||||||
|
|
||||||
|
|
||||||
|
### `NewRegistry`
|
||||||
|
|
||||||
|
```go
|
||||||
|
func NewRegistry() *Registry
|
||||||
|
```
|
||||||
|
|
||||||
|
NewRegistry creates an empty agent registry.
|
||||||
|
Usage: call NewRegistry(...) to create a ready-to-use value.
|
||||||
Loading…
Add table
Reference in a new issue