Documentation
¶
Overview ¶
Package budgets implements the AAuth Budgets protocol companion.
Index ¶
- Constants
- Variables
- func AccountedSpend(grant Value, consumed *ConsumptionRecord) (int64, error)
- func CheckUsageResponse(request UsageRequest, caller string, response UsageResponse) error
- func FormatAuthTokenRequirement(value aauth.AuthTokenRequirement, reason Reason) (string, error)
- func FormatConsentAmount(value Value) (string, error)
- func FormatFeedback(feedback Feedback) (string, error)
- func FormatTrailer(cost int64) (string, error)
- func Free(ceiling, metered int64, allocations []Allocation, asOf time.Time) (int64, error)
- func IsTokenClaimError(err error) bool
- func MintAuthToken(key jose.SigningKey, claims aauth.AuthTokenClaims, grant Value) (string, error)
- func MintResourceToken(key jose.SigningKey, claims aauth.ResourceTokenClaims, offer Value, ...) (string, error)
- func SanitizeDescription(description string) (string, error)
- func SettledRemaining(feedback Feedback) (int64, error)
- func TokenCarriesClaims(compact string) (bool, error)
- func TokenClaimError(err error) error
- func UnsettledAmount(allocations []Allocation, asOf time.Time) (int64, error)
- func UsageResponseSignOptions() signaturekey.ResponseSignOptions
- func ValidateConsumptionRecord(consumed *ConsumptionRecord, presentedJTI string) error
- func ValidateDeclaredValue(declarations []UnitDeclaration, value Value) error
- func ValidateFeedback(grant Value, feedback Feedback) error
- func ValidateFeedbackUnit(unit Unit) error
- func ValidateNarrowing(offered, granted Value) error
- func ValidateUnitDeclarations(declarations []UnitDeclaration) error
- func VerifyResourceToken(ctx context.Context, compact string, resolver signaturekey.KeyResolver, ...) (aauth.ResourceTokenClaims, Value, *ConsumptionRecord, error)
- func VerifyUsageResponse(ctx context.Context, request *http.Request, status int, header http.Header, ...) (signaturekey.VerifiedResponse, error)
- type Allocation
- type ConsumptionRecord
- type Feedback
- func ApplyTrailer(header Feedback, trailer []string) (Feedback, error)
- func NewRefusalFeedback(grant Value, remaining int64, required *int64) (Feedback, error)
- func NewReservedFeedback(grant Value, remaining, reserved int64) (Feedback, error)
- func NewSuccessFeedback(grant Value, cost, remaining int64) (Feedback, error)
- func ParseFeedback(values []string) (Feedback, error)
- type Reason
- type Unit
- type UnitDeclaration
- type UsageCalendar
- type UsageRequest
- type UsageResponse
- type UsageResult
- type UsageSignatureCheck
- type Value
Constants ¶
const MaximumAmount int64 = 999_999_999_999_999
MaximumAmount is the 15-digit limit shared by Budget JSON values and RFC 9651 Integer members.
Variables ¶
var ErrUsageRequest = errors.New("budgets: usage request is invalid")
ErrUsageRequest marks a usage body the endpoint rejects as invalid_request.
var ErrUsageUnsigned = errors.New("budgets: usage response is not signed")
ErrUsageUnsigned reports a usage response that carries no signature when the caller required one.
Functions ¶
func AccountedSpend ¶
func AccountedSpend(grant Value, consumed *ConsumptionRecord) (int64, error)
AccountedSpend is what an issuer holds against one allocation until a usage reading settles it. A missing consumption record is the full grant. A record replaces that assumption and is not added to it.
func CheckUsageResponse ¶
func CheckUsageResponse(request UsageRequest, caller string, response UsageResponse) error
CheckUsageResponse reports whether a success body answers this request for this caller. An omitted usage object is a valid answer to a scope key.
func FormatAuthTokenRequirement ¶
func FormatAuthTokenRequirement(value aauth.AuthTokenRequirement, reason Reason) (string, error)
FormatAuthTokenRequirement formats the Core auth-token requirement with one typed Budget reason parameter.
func FormatConsentAmount ¶
FormatConsentAmount renders a budget the way a Person Server shows it to a person. USD at decimals 6 becomes a dollar figure, keeping extra fraction digits when the amount is not an exact cent. Other units are the scaled number plus the unit name.
func FormatFeedback ¶
FormatFeedback emits the canonical RFC 9651 Dictionary form.
func FormatTrailer ¶
FormatTrailer emits the cost-only AAuth-Budget trailer. A trailer must not restate a member the header carried.
func Free ¶
Free is ceiling − metered − unsettled allocations. A consumption record is not an input: it refines a live allocation and does not settle it. A negative result means the ceiling is already exceeded.
func IsTokenClaimError ¶
IsTokenClaimError reports whether Core token verification succeeded but the Budget companion claims were malformed. Token endpoints use this distinction to return the Budgets protocol's registered invalid_budget error.
func MintAuthToken ¶
func MintAuthToken(key jose.SigningKey, claims aauth.AuthTokenClaims, grant Value) (string, error)
MintAuthToken adds one validated Budget grant to Core Auth-token claims.
func MintResourceToken ¶
func MintResourceToken( key jose.SigningKey, claims aauth.ResourceTokenClaims, offer Value, consumed *ConsumptionRecord, ) (string, error)
MintResourceToken adds one validated Budget offer to Core Resource-token claims. The optional consumption record reports what the Auth token presented on the answered request has consumed, so its jti is the token's presented_jti.
func SanitizeDescription ¶
SanitizeDescription removes active HTML and dangerous link schemes from a resource-supplied Markdown unit description before a consent screen renders it. The stored metadata value is unchanged; callers render the result. Numeric character references and a small set of named entities are decoded before the check, so an encoded scheme such as javascript: is not a link. Reference-style definitions are checked as well as inline links. javascript:, vbscript:, and data: are removed from those destinations.
func SettledRemaining ¶
SettledRemaining is remaining + reserved - cost after a streamed response. Remaining is already net of the reservation, so the unspent hold returns to the grant. A header that omitted cost uses the full reservation.
func TokenCarriesClaims ¶
TokenCarriesClaims reports whether an unverified compact token names a Budget claim, including partial and case-variant forms that must route to strict Budget verification.
func TokenClaimError ¶
TokenClaimError marks an error found after Core token verification while consuming Budget companion claims. Endpoints use it to return the registered invalid_budget response for composed token profiles too.
func UnsettledAmount ¶
func UnsettledAmount(allocations []Allocation, asOf time.Time) (int64, error)
UnsettledAmount is the sum of allocations a reading at asOf has not settled.
func UsageResponseSignOptions ¶
func UsageResponseSignOptions() signaturekey.ResponseSignOptions
UsageResponseSignOptions is the coverage of a signed usage response: @status, content-type and content-digest, bound to the request by @authority and @path under req. A Resource signs with these options and its jwks_uri key; VerifyUsageResponse requires the same coverage.
func ValidateConsumptionRecord ¶
func ValidateConsumptionRecord(consumed *ConsumptionRecord, presentedJTI string) error
ValidateConsumptionRecord checks an optional Resource-token consumption record. A record names the Auth token presented on the request the Resource token answers, which the token carries as presented_jti.
func ValidateDeclaredValue ¶
func ValidateDeclaredValue(declarations []UnitDeclaration, value Value) error
ValidateDeclaredValue checks that a signed offer or grant uses one declared denomination and does not exceed its advertised maximum when present.
func ValidateFeedback ¶
ValidateFeedback checks unsigned informational feedback against the signed Auth-token budget. An omitted unit pair remains valid because the pair is optional; a present pair must match exactly.
func ValidateFeedbackUnit ¶
ValidateFeedbackUnit checks that a JSON Budget unit is representable as an RFC 9651 String in AAuth-Budget. The token object permits arbitrary UTF-8, but a metering profile that emits the response field must establish this narrower carrier before any charge.
func ValidateNarrowing ¶
ValidateNarrowing requires the same denomination and an amount no greater than the resource's offer.
func ValidateUnitDeclarations ¶
func ValidateUnitDeclarations(declarations []UnitDeclaration) error
ValidateUnitDeclarations requires valid entries and one scale per unit identifier.
func VerifyResourceToken ¶
func VerifyResourceToken( ctx context.Context, compact string, resolver signaturekey.KeyResolver, clock aauth.Clock, ) (aauth.ResourceTokenClaims, Value, *ConsumptionRecord, error)
VerifyResourceToken verifies Core trust and consumes the complete Budget companion claim set.
func VerifyUsageResponse ¶
func VerifyUsageResponse( ctx context.Context, request *http.Request, status int, header http.Header, body []byte, resource string, resolver signaturekey.KeyResolver, clock aauth.Clock, ) (signaturekey.VerifiedResponse, error)
VerifyUsageResponse verifies a signed usage response: status, header and the exact body bytes the caller received, and request, the usage query the caller sent. The signature must cover what UsageResponseSignOptions covers and verify under a key from resource's own metadata, so a response signed by any other party, or for another request, is refused. The PS or AS that keeps the exact body and header holds a statement the resource cannot later disown.
Types ¶
type Allocation ¶
Allocation is one issuer-side budget that has not necessarily been settled. RevocationRecordedAt is set only when the resource recorded the revocation. revocation_unsupported and revocation_unavailable leave it zero and settle at ExpiresAt.
func (Allocation) Settled ¶
func (allocation Allocation) Settled(asOf time.Time) bool
Settled reports whether a usage reading at asOf releases the allocation. A recorded revocation settles at that recording time. Every other allocation settles when exp is at or before asOf. A consumption record does not settle.
type ConsumptionRecord ¶
type ConsumptionRecord struct {
// contains filtered or unexported fields
}
ConsumptionRecord reports metered consumption against one prior Auth token.
func ConsumptionForPresentedGrant ¶
func ConsumptionForPresentedGrant(jti string, grant Value, remaining int64) (ConsumptionRecord, error)
ConsumptionForPresentedGrant is the consumption record for an Auth token whose metered spend is the granted amount minus the uncommitted remainder. Remaining must be that uncommitted remainder. A figure already net of in-flight holds makes this record count those holds as consumed. The record uses the grant's scale. A caller that would restate the figure in another scale omits the record instead of calling this function.
func NewConsumptionRecord ¶
func NewConsumptionRecord(jti string, consumed int64) (ConsumptionRecord, error)
NewConsumptionRecord validates one prior Auth-token consumption record.
func ParseConsumptionRecordJSON ¶
func ParseConsumptionRecordJSON(raw json.RawMessage, presentedJTI string) (*ConsumptionRecord, error)
ParseConsumptionRecordJSON parses the optional budget_consumed claim, a single consumption record for the presented Auth token. A nil claim is absent.
func (ConsumptionRecord) Consumed ¶
func (record ConsumptionRecord) Consumed() int64
Consumed returns the amount metered against the prior Auth token.
func (ConsumptionRecord) JTI ¶
func (record ConsumptionRecord) JTI() string
JTI returns the prior Auth token identifier.
func (ConsumptionRecord) MarshalJSON ¶
func (record ConsumptionRecord) MarshalJSON() ([]byte, error)
MarshalJSON emits the exact Budget consumption-record object.
func (*ConsumptionRecord) UnmarshalJSON ¶
func (record *ConsumptionRecord) UnmarshalJSON(data []byte) error
UnmarshalJSON accepts only the exact Budget consumption-record object.
type Feedback ¶
type Feedback struct {
// contains filtered or unexported fields
}
Feedback is the parsed AAuth-Budget response field. A fixed-price success carries cost. A refusal carries remaining and maybe required. A streamed response carries reserved and omits cost until a trailer, if any, arrives.
func ApplyTrailer ¶
ApplyTrailer merges a cost-only trailer into a header. An empty trailer leaves the header unchanged: a recipient must not treat the trailer as necessary. Any member other than cost is rejected, including members the header already carried and members this profile does not recognize. The general header rule ignores unknown members; the trailer rule allows cost and nothing else, and this function follows the trailer rule.
func NewRefusalFeedback ¶
NewRefusalFeedback constructs feedback for an exhausted or insufficient fixed-price request. Required is omitted when the Resource does not state a maximum cost for the refused request.
func NewReservedFeedback ¶
NewReservedFeedback constructs the header for a response whose cost is not known yet. Remaining is already net of the reservation. The header omits cost.
func NewSuccessFeedback ¶
NewSuccessFeedback constructs feedback for a completed fixed-price request.
func ParseFeedback ¶
ParseFeedback parses one or more AAuth-Budget field lines as an RFC 9651 Dictionary. Unknown members are ignored.
func (Feedback) Required ¶
Required returns the computed maximum cost of a refused request when reported.
type Reason ¶
type Reason string
Reason is one Budget-specific reason on an auth-token requirement.
func ParseAuthTokenRequirement ¶
func ParseAuthTokenRequirement(values []string) (aauth.AuthTokenRequirement, Reason, error)
ParseAuthTokenRequirement parses the Core auth-token requirement and its required Budget reason parameter. Unrelated extension parameters remain ignored as required by the base extension model.
func ParseOptionalAuthTokenRequirement ¶
func ParseOptionalAuthTokenRequirement(values []string) (aauth.AuthTokenRequirement, Reason, bool, error)
ParseOptionalAuthTokenRequirement parses the Core auth-token requirement and, when present, one typed Budget reason. A missing reason is the ordinary Core step-up shape; an unknown or malformed present reason fails.
func ParseReason ¶
ParseReason validates a Budget-specific requirement reason.
type Unit ¶
type Unit struct {
// contains filtered or unexported fields
}
Unit is one resource-selected Budget denomination and scale.
type UnitDeclaration ¶
type UnitDeclaration struct {
// contains filtered or unexported fields
}
UnitDeclaration is one budget_units Resource-metadata entry. Unit and scale identify the denomination. Maximum is optional in the protocol; a host may require it for a bounded pricing profile.
func FindUnitDeclaration ¶
func FindUnitDeclaration(declarations []UnitDeclaration, unit Unit) (UnitDeclaration, bool)
FindUnitDeclaration returns the declaration for one exact denomination.
func NewBoundedUnitDeclaration ¶
func NewBoundedUnitDeclaration(unit Unit, maximum int64, description string) (UnitDeclaration, error)
NewBoundedUnitDeclaration constructs a declaration with an advertised maximum amount for one Auth token.
func NewUnitDeclaration ¶
func NewUnitDeclaration(unit Unit, description string) (UnitDeclaration, error)
NewUnitDeclaration constructs a declaration without an advertised maximum.
func (UnitDeclaration) Description ¶
func (declaration UnitDeclaration) Description() string
Description returns the optional Markdown description.
func (UnitDeclaration) MarshalJSON ¶
func (declaration UnitDeclaration) MarshalJSON() ([]byte, error)
MarshalJSON emits the flat budget_units metadata object.
func (UnitDeclaration) Maximum ¶
func (declaration UnitDeclaration) Maximum() (int64, bool)
Maximum returns the advertised maximum when present.
func (UnitDeclaration) Unit ¶
func (declaration UnitDeclaration) Unit() Unit
Unit returns the declared denomination and scale.
func (*UnitDeclaration) UnmarshalJSON ¶
func (declaration *UnitDeclaration) UnmarshalJSON(data []byte) error
UnmarshalJSON accepts one strict budget_units metadata object.
type UsageCalendar ¶
UsageCalendar holds the counters a resource chose to report. AllTime is required when the usage object is present. A nil period was omitted.
type UsageRequest ¶
type UsageRequest struct {
Subject string
Tenant string
MissionS256 string
PersonServer string
JKTs []string
}
UsageRequest is the JSON body of a signed usage query. At most one of Subject, Tenant, and MissionS256 is set. JKTs may accompany that scope key or stand alone. PersonServer is the ps member an Access Server sends with a scope key; a Person Server omits it.
func ParseUsageRequest ¶
func ParseUsageRequest(data []byte) (UsageRequest, error)
ParseUsageRequest accepts one strict usage-request object.
func (UsageRequest) HasScope ¶
func (request UsageRequest) HasScope() bool
HasScope reports whether the request names sub, tenant, or mission_s256.
func (UsageRequest) MarshalJSON ¶
func (request UsageRequest) MarshalJSON() ([]byte, error)
type UsageResponse ¶
type UsageResponse struct {
AsOf int64
Audience string
Unit Unit
Subject string
Tenant string
MissionS256 string
Usage *UsageCalendar
JKTs map[string]int64
JKTsPresent bool
}
UsageResponse is one usage-endpoint success body.
func ParseUsageResponse ¶
func ParseUsageResponse(data []byte) (UsageResponse, error)
ParseUsageResponse accepts one strict usage success body.
func PostUsage ¶
func PostUsage( ctx context.Context, endpoint string, key jose.SigningKey, caller string, discoveryDocument string, clock aauth.Clock, request UsageRequest, client *http.Client, ) (UsageResponse, error)
PostUsage sends one signed usage query and parses the success body. It does not check a response signature; PostUsageChecked does. A nil client refuses redirects.
type UsageResult ¶
type UsageResult struct {
Response UsageResponse
Signed bool
ExactBody []byte
Header http.Header
}
UsageResult is a checked usage answer. Signed reports a verified resource signature. ExactBody and Header are the bytes and fields as received, so a caller can retain a signed statement as evidence.
func PostUsageChecked ¶
func PostUsageChecked( ctx context.Context, endpoint string, key jose.SigningKey, caller string, discoveryDocument string, clock aauth.Clock, request UsageRequest, check UsageSignatureCheck, ) (UsageResult, error)
PostUsageChecked sends one signed usage query, as PostUsage does, and verifies the response signature per check before parsing the body.
type UsageSignatureCheck ¶
type UsageSignatureCheck struct {
Resource string
KeyResolver signaturekey.KeyResolver
RequireSignature bool
Client *http.Client
}
UsageSignatureCheck tells PostUsageChecked how to treat the resource's response signature. Resource is the resource identifier whose usage_endpoint is called, and KeyResolver resolves its jwks_uri keys. Signing is RECOMMENDED rather than REQUIRED, so an unsigned response is read and reported as unsigned unless RequireSignature is set. A response that carries a signature which does not verify is always refused. Client defaults to one that refuses redirects.
type Value ¶
type Value struct {
// contains filtered or unexported fields
}
Value is one non-negative Budget amount in a resource-selected unit.
func ParseValueJSON ¶
ParseValueJSON parses exactly one strict Budget object.
func VerifyAuthToken ¶
func VerifyAuthToken( ctx context.Context, compact string, resolver signaturekey.KeyResolver, clock aauth.Clock, ) (aauth.AuthTokenClaims, Value, error)
VerifyAuthToken verifies Core trust and consumes the complete Budget companion claim set.
func (Value) MarshalJSON ¶
MarshalJSON emits the exact Budget object.
func (*Value) UnmarshalJSON ¶
UnmarshalJSON accepts only the exact Budget object.