196 lines
6.4 KiB
Go
196 lines
6.4 KiB
Go
// Package ucan provides UCAN v1.0.0-rc.1 compliant authorization
|
|
// for the Sonr network using the official go-ucan library.
|
|
//
|
|
// This package wraps code.sonr.org/go/ucan to provide:
|
|
// - Delegation creation and validation
|
|
// - Invocation creation and validation
|
|
// - Policy evaluation
|
|
// - Sonr-specific capability types (vault, did, dwn)
|
|
//
|
|
// UCAN Envelope Format (DAG-CBOR):
|
|
//
|
|
// [
|
|
// Signature, // Varsig-encoded signature
|
|
// {
|
|
// "h": VarsigHeader, // Algorithm metadata
|
|
// "ucan/dlg@1.0.0-rc.1": DelegationPayload // or "ucan/inv@1.0.0-rc.1"
|
|
// }
|
|
// ]
|
|
package ucan
|
|
|
|
import (
|
|
"code.sonr.org/go/ucan/pkg/command"
|
|
"code.sonr.org/go/ucan/pkg/policy"
|
|
"code.sonr.org/go/ucan/token/delegation"
|
|
"code.sonr.org/go/ucan/token/invocation"
|
|
)
|
|
|
|
// Re-export key types from go-ucan for convenience.
|
|
// Users should import this package instead of go-ucan directly
|
|
// for Sonr-specific functionality.
|
|
type (
|
|
// Delegation is an immutable UCAN delegation token.
|
|
Delegation = delegation.Token
|
|
|
|
// Invocation is an immutable UCAN invocation token.
|
|
Invocation = invocation.Token
|
|
|
|
// Command is a validated UCAN command string (e.g., "/vault/read").
|
|
Command = command.Command
|
|
|
|
// Policy is a list of policy statements that constrain invocation arguments.
|
|
Policy = policy.Policy
|
|
|
|
// Statement is a single policy statement (equality, like, and, or, etc.).
|
|
Statement = policy.Statement
|
|
|
|
// DelegationOption configures optional fields when creating a delegation.
|
|
DelegationOption = delegation.Option
|
|
|
|
// InvocationOption configures optional fields when creating an invocation.
|
|
InvocationOption = invocation.Option
|
|
)
|
|
|
|
// Re-export constructors
|
|
var (
|
|
// NewDelegation creates a delegation: "(issuer) allows (audience) to perform (cmd+pol) on (subject)".
|
|
NewDelegation = delegation.New
|
|
|
|
// NewRootDelegation creates a root delegation where subject == issuer.
|
|
NewRootDelegation = delegation.Root
|
|
|
|
// NewPowerlineDelegation creates a powerline delegation (subject = nil).
|
|
// Powerline automatically delegates all future delegations regardless of subject.
|
|
NewPowerlineDelegation = delegation.Powerline
|
|
|
|
// NewInvocation creates an invocation: "(issuer) executes (command) on (subject)".
|
|
NewInvocation = invocation.New
|
|
|
|
// ParseCommand validates and parses a command string.
|
|
ParseCommand = command.Parse
|
|
|
|
// MustParseCommand parses a command string, panicking on error.
|
|
MustParseCommand = command.MustParse
|
|
|
|
// TopCommand returns "/" - the most powerful capability (grants everything).
|
|
TopCommand = command.Top
|
|
|
|
// NewCommand creates a command from segments (e.g., NewCommand("vault", "read") -> "/vault/read").
|
|
NewCommand = command.New
|
|
)
|
|
|
|
// Re-export delegation options
|
|
var (
|
|
// WithExpiration sets the delegation's expiration time.
|
|
WithExpiration = delegation.WithExpiration
|
|
|
|
// WithExpirationIn sets expiration to now + duration.
|
|
WithExpirationIn = delegation.WithExpirationIn
|
|
|
|
// WithNotBefore sets when the delegation becomes valid.
|
|
WithNotBefore = delegation.WithNotBefore
|
|
|
|
// WithNotBeforeIn sets not-before to now + duration.
|
|
WithNotBeforeIn = delegation.WithNotBeforeIn
|
|
|
|
// WithDelegationMeta adds metadata to the delegation.
|
|
WithDelegationMeta = delegation.WithMeta
|
|
|
|
// WithDelegationNonce sets a custom nonce (default: random 12 bytes).
|
|
WithDelegationNonce = delegation.WithNonce
|
|
)
|
|
|
|
// Re-export invocation options
|
|
var (
|
|
// WithArgument adds a single argument to the invocation.
|
|
WithArgument = invocation.WithArgument
|
|
|
|
// WithAudience sets the invocation's audience (executor if different from subject).
|
|
WithAudience = invocation.WithAudience
|
|
|
|
// WithInvocationMeta adds metadata to the invocation.
|
|
WithInvocationMeta = invocation.WithMeta
|
|
|
|
// WithInvocationNonce sets a custom nonce.
|
|
WithInvocationNonce = invocation.WithNonce
|
|
|
|
// WithEmptyNonce sets an empty nonce for idempotent operations.
|
|
WithEmptyNonce = invocation.WithEmptyNonce
|
|
|
|
// WithInvocationExpiration sets the invocation's expiration time.
|
|
WithInvocationExpiration = invocation.WithExpiration
|
|
|
|
// WithInvocationExpirationIn sets expiration to now + duration.
|
|
WithInvocationExpirationIn = invocation.WithExpirationIn
|
|
|
|
// WithIssuedAt sets when the invocation was created.
|
|
WithIssuedAt = invocation.WithIssuedAt
|
|
|
|
// WithCause sets the receipt CID that enqueued this task.
|
|
WithCause = invocation.WithCause
|
|
)
|
|
|
|
// Standard Sonr commands following UCAN v1.0.0-rc.1 command format.
|
|
// Commands must be lowercase, start with '/', and have no trailing slash.
|
|
const (
|
|
// Vault commands
|
|
CmdVaultRead = "/vault/read"
|
|
CmdVaultWrite = "/vault/write"
|
|
CmdVaultSign = "/vault/sign"
|
|
CmdVaultExport = "/vault/export"
|
|
CmdVaultImport = "/vault/import"
|
|
CmdVaultDelete = "/vault/delete"
|
|
CmdVaultAdmin = "/vault/admin"
|
|
CmdVault = "/vault" // Superuser - grants all vault commands
|
|
|
|
// DID commands
|
|
CmdDIDCreate = "/did/create"
|
|
CmdDIDUpdate = "/did/update"
|
|
CmdDIDDeactivate = "/did/deactivate"
|
|
CmdDID = "/did" // Superuser - grants all DID commands
|
|
|
|
// DWN commands
|
|
CmdDWNRecordsWrite = "/dwn/records/write"
|
|
CmdDWNRecordsRead = "/dwn/records/read"
|
|
CmdDWNRecordsDelete = "/dwn/records/delete"
|
|
CmdDWN = "/dwn" // Superuser - grants all DWN commands
|
|
|
|
// UCAN meta commands
|
|
CmdUCANRevoke = "/ucan/revoke"
|
|
|
|
// Root command - grants everything
|
|
CmdRoot = "/"
|
|
)
|
|
|
|
// Pre-parsed Sonr commands for convenience
|
|
var (
|
|
VaultRead = command.MustParse(CmdVaultRead)
|
|
VaultWrite = command.MustParse(CmdVaultWrite)
|
|
VaultSign = command.MustParse(CmdVaultSign)
|
|
VaultExport = command.MustParse(CmdVaultExport)
|
|
VaultImport = command.MustParse(CmdVaultImport)
|
|
VaultDelete = command.MustParse(CmdVaultDelete)
|
|
VaultAdmin = command.MustParse(CmdVaultAdmin)
|
|
Vault = command.MustParse(CmdVault)
|
|
|
|
DIDCreate = command.MustParse(CmdDIDCreate)
|
|
DIDUpdate = command.MustParse(CmdDIDUpdate)
|
|
DIDDeactivate = command.MustParse(CmdDIDDeactivate)
|
|
DID = command.MustParse(CmdDID)
|
|
|
|
DWNRecordsWrite = command.MustParse(CmdDWNRecordsWrite)
|
|
DWNRecordsRead = command.MustParse(CmdDWNRecordsRead)
|
|
DWNRecordsDelete = command.MustParse(CmdDWNRecordsDelete)
|
|
DWN = command.MustParse(CmdDWN)
|
|
|
|
UCANRevoke = command.MustParse(CmdUCANRevoke)
|
|
Root = command.Top()
|
|
)
|
|
|
|
// CommandSubsumes checks if parent command subsumes child command.
|
|
// A command subsumes another if the child is a path extension of parent.
|
|
// Example: "/vault" subsumes "/vault/read" and "/vault/write"
|
|
func CommandSubsumes(parent, child Command) bool {
|
|
return parent.Covers(child)
|
|
}
|