Documentation
¶
Overview ¶
Network manifest schema types and validation. gopkg.in/yaml.v3 is imported here because ParseNetworkManifest is the canonical constructor for NetworkManifest.
Index ¶
- Constants
- func FirstNonEmptyCode(errs []Error, defaultCode string) string
- func IsAtLeastV2(version string) bool
- func IsKeyStatusUsable(status string) bool
- func ResolveCallerID(reqContext map[string]interface{}, role Role) string
- func ResolveNetworkID(reqContext map[string]interface{}) string
- func ResolveSubscriberID(reqContext map[string]interface{}, role Role) string
- type AckNoCallbackErr
- type BecknErrorer
- type CodedErr
- func NewBadReqErr(code string, err error) *CodedErr
- func NewCodedErr(httpStatus int, code string, err error) *CodedErr
- func NewNotFoundErr(code string, err error) *CodedErr
- func NewSignValidationErr(code string, err error) *CodedErr
- func WrapExtractContextErr(prefix string, becknErr *Error) *CodedErr
- type ContextKey
- type Error
- type ErrorDetails
- type Keyset
- type ManifestDocument
- type ManifestMetadata
- type Message
- type NetworkManifest
- type NetworkManifestBundle
- type NetworkManifestFile
- type NetworkManifestGovernance
- type NetworkManifestPolicies
- type NetworkManifestPublisher
- type NodeManifest
- type NodeManifestGovernance
- type NodeManifestSchema
- type RegistryMetadata
- type Response
- type ResponseStepContext
- type Role
- type Route
- type SchemaObject
- type SchemaValidationErr
- type Status
- type StepContext
- type Subscriber
- type SubscriberRecord
- type Subscription
Constants ¶
const ( // NetworkManifestType is the manifest_type value for network manifests. NetworkManifestType = "network-manifest" // NodeManifestType is the manifest_type value for node manifests. NodeManifestType = "node-manifest" // PolicyTypeRego is the policies.type value for Rego policy manifests. PolicyTypeRego = "rego" // PolicySourceBundle is the policies.source value for OPA bundle policies. PolicySourceBundle = "bundle" // PolicySourceFile is the policies.source value for single Rego file policies. PolicySourceFile = "file" )
const ( // VersionPolicyLatest resolves to the highest version in SupportedVersions. VersionPolicyLatest = "latest" // VersionPolicyPinned resolves to the explicit PinnedVersion field. VersionPolicyPinned = "pinned" )
const ( AuthHeaderSubscriber string = "Authorization" AuthHeaderGateway string = "X-Gateway-Authorization" UnaAuthorizedHeaderSubscriber string = "WWW-Authenticate" UnaAuthorizedHeaderGateway string = "Proxy-Authenticate" )
Authorization-related constants for headers.
const ProtocolVersionV2 = "2.0.0"
ProtocolVersionV2 is the Beckn protocol version string for the v2.0.0 release. Steps and response functions gate v2+ behaviour on this value.
Variables ¶
This section is empty.
Functions ¶
func FirstNonEmptyCode ¶ added in v1.8.1
FirstNonEmptyCode returns the first non-empty Code among errs, in order, or defaultCode if none is set. Used when multiple causes must be reduced to one representative Code for the wire — the other causes' text is still carried in full elsewhere (e.g. a joined Message), only their Code is dropped, since a single Error can only carry one code.
func IsAtLeastV2 ¶ added in v1.7.0
IsAtLeastV2 reports whether the given protocol version string is 2.0.0 or later. The check is intentionally major-version based: any version with major >= 2 (e.g. "2.1.0", "3.0.0") is treated as v2-compatible, while legacy 1.x versions and empty/unknown strings return false.
func IsKeyStatusUsable ¶ added in v1.8.1
IsKeyStatusUsable reports whether a subscriber's registry Status still permits its key to be used for signature verification.
func ResolveCallerID ¶ added in v1.7.1
ResolveCallerID returns the ID of the other party in a Beckn exchange — i.e. who sent the inbound message — from a parsed Beckn context map. For BPP role: the caller is the BAP (bap_id / bapId / senderId). For BAP role: the caller is the BPP (bpp_id / bppId / receiverId). Returns "" when the role is not BAP/BPP or no matching key is found.
func ResolveNetworkID ¶ added in v1.8.0
ResolveNetworkID returns context.network_id from a parsed Beckn context map, trying "network_id" (snake_case) then "networkId" (camelCase). Returns "" when absent, empty, or not a string under either alias.
func ResolveSubscriberID ¶ added in v1.7.1
ResolveSubscriberID returns the node's own subscriber ID from a parsed Beckn context map. For BAP role: returns bap_id / bapId / senderId. For BPP role: returns bpp_id / bppId / receiverId. Returns "" when the role is not BAP/BPP or no matching key is found.
Types ¶
type AckNoCallbackErr ¶ added in v1.7.0
type AckNoCallbackErr struct {
// Status is ACK when the request was accepted but no callback will follow,
// or NACK when the request was outright rejected.
Status Status
// Err explains why no callback will be sent. Required by the spec.
Err *Error
}
AckNoCallbackErr is returned by a step when the receiver has authenticated and accepted the request but will not send an async callback — for example, no matching catalog, inventory unavailable, or provider closed. ONIX maps this to HTTP 202 Accepted using the v2 flat response shape. For protocol versions prior to 2.0.0 this error falls through to a 500 Internal Server Error.
func NewAckNoCallbackErr ¶ added in v1.7.0
func NewAckNoCallbackErr(status Status, err *Error) *AckNoCallbackErr
NewAckNoCallbackErr constructs an AckNoCallbackErr. Use StatusACK for "accepted but no callback" and StatusNACK for outright rejection. Panics if err is nil — the spec requires an error explanation on every AckNoCallback (202) response.
func (*AckNoCallbackErr) BecknError ¶ added in v1.7.0
func (e *AckNoCallbackErr) BecknError() *Error
BecknError returns the wrapped *Error payload.
func (*AckNoCallbackErr) Error ¶ added in v1.7.0
func (e *AckNoCallbackErr) Error() string
Error implements the error interface.
type BecknErrorer ¶ added in v1.8.1
BecknErrorer is implemented by any error type that can produce its own *Error NACK representation. nackBecknError (core/module/handler/responsestep.go) dispatches on a short list of concrete types first (SchemaValidationErr, CodedErr, AckNoCallbackErr) for their HTTP status codes, then falls back to this interface for any other type — so a new error type can be wired into NACK dispatch by implementing BecknError() *Error alone, without core importing the plugin package that defines it. The fallback always answers 400; a type needing another status should return a *CodedErr instead.
type CodedErr ¶ added in v1.8.2
type CodedErr struct {
// Code is the taxonomy value for this failure's specific cause, or ""
// if unclassified, in which case BecknError() reports defaultCode.
Code string
// contains filtered or unexported fields
}
CodedErr wraps one cause with an optional taxonomy code and the HTTP status to NACK it with. It replaces BadReqErr, SignValidationErr and NotFoundErr, which stored the same fields and differed only in the status nackBecknError (core/module/handler/responsestep.go) picked for each by type switch. That status is now set at construction.
Use NewCodedErr, or NewBadReqErr, NewSignValidationErr and NewNotFoundErr for the 400, 401 and 404 cases and their message prefixes. Status, prefix and default code are unexported, so a usable value comes from a constructor.
SchemaValidationErr and AckNoCallbackErr stay separate. They differ in shape, not just status.
func NewBadReqErr ¶
NewBadReqErr creates a 400 CodedErr. Pass code "" to leave the failure unclassified, reporting defaultBadReqCode, or a specific taxonomy code when the caller knows one (e.g. a policy checker classifying a denial onto the Beckn v2.0.0 POL_* codes).
func NewCodedErr ¶ added in v1.8.2
NewCodedErr creates a CodedErr with an explicit HTTP status and taxonomy code. A plugin that classifies several kinds of failure, such as vcvalidator, needs only this constructor.
The status is explicit rather than derived from the code's family prefix, which does not determine it: NET_* alone spans 404, 500, 502 and 503.
func NewNotFoundErr ¶
NewNotFoundErr creates a 404 CodedErr for a requested endpoint or entity that does not exist. Pass code "" to leave the failure unclassified, reporting defaultNotFoundCode.
func NewSignValidationErr ¶
NewSignValidationErr creates a 401 CodedErr for a request whose authenticity could not be established. Pass code "" to leave the failure unclassified, reporting defaultSignValidationCode.
The "Signature Validation Error: " message prefix was accurate for the original sole caller (signvalidator.go, exclusively real signature failures). vcvalidator (see #870/#884) also uses it for non-signature causes — expiry, revocation, DID-resolution failures, issuer mismatch — so the human-readable message can now read e.g. "Signature Validation Error: CREDENTIAL_EXPIRED: ...". The structured Code field is correct either way; only this message text is misleading for those causes. Deliberately left as-is: fixing it is a cross-cutting change affecting every caller, deferred rather than folded into #884's scope.
func WrapExtractContextErr ¶ added in v1.8.1
WrapExtractContextErr converts an ExtractContext failure into a 400 *CodedErr carrying becknErr's Code, for callers that need an error value rather than the bare *Error ExtractContext returns. becknErr is wrapped with prefix via %w, so errors.Is/errors.As still reach any cause set on it (via Error.Unwrap) as well as becknErr itself. Only call this when becknErr is non-nil.
func (*CodedErr) BecknError ¶ added in v1.8.2
BecknError builds the *Error NACK payload from the resolved code and the constructor's prefix prepended to the wrapped error's text.
func (*CodedErr) Error ¶ added in v1.8.2
Error returns the wrapped cause's text, or "" when a CodedErr was built without a cause. BecknError runs while the handler builds the NACK, so a panic here would drop the request instead of answering it.
func (*CodedErr) HTTPStatus ¶ added in v1.8.2
HTTPStatus returns the status to NACK with. Anything outside the 4xx/5xx range reports 400 instead, since a NACK must not be sent with a success status and a value built without a constructor carries no status at all. 400 is also what core answers for any other BecknErrorer.
type ContextKey ¶
type ContextKey string
ContextKey is a custom type used as a key for storing and retrieving values in a context.
const ( // ContextKeyTxnID is the context key used to store and retrieve the transaction ID in a request context. ContextKeyTxnID ContextKey = "transaction_id" // ContextKeyMsgID is the context key used to store and retrieve the message ID in a request context. ContextKeyMsgID ContextKey = "message_id" // ContextKeySubscriberID is the context key used to store and retrieve the subscriber ID in a request context. ContextKeySubscriberID ContextKey = "subscriber_id" // ContextKeyModuleID is the context key for storing and retrieving the model ID from a request context. ContextKeyModuleID ContextKey = "module_id" // ContextKeyParentID is the context key for storing and retrieving the parent ID from a request context ContextKeyParentID ContextKey = "parent_id" // ContextKeyRemoteID is the context key for the caller who is calling the bap/bpp ContextKeyRemoteID ContextKey = "remote_id" // ContextKeyProtocolVersion is the context key for the Beckn protocol version // extracted from context.version in the inbound request body. ContextKeyProtocolVersion ContextKey = "protocol_version" // ContextKeyNetworkID is the context key for the network identifier extracted from // context.network_id (or context.networkId) in the inbound request body. ContextKeyNetworkID ContextKey = "network_id" )
func ParseContextKey ¶
func ParseContextKey(v string) (ContextKey, error)
ParseContextKey converts a string into a valid ContextKey.
func (*ContextKey) UnmarshalYAML ¶
func (k *ContextKey) UnmarshalYAML(unmarshal func(interface{}) error) error
UnmarshalYAML ensures that only known context keys are accepted during YAML unmarshalling.
type Error ¶
type Error struct {
Code string `json:"code"`
Message string `json:"message"`
Details *ErrorDetails `json:"details,omitempty"`
// contains filtered or unexported fields
}
Error represents a standard error response.
func ExtractContext ¶ added in v1.8.1
func ExtractContext(body []byte) (req map[string]interface{}, reqContext map[string]interface{}, becknErr *Error)
ExtractContext decodes body as JSON and returns both the full decoded body and its "context" field as a map[string]interface{}, classifying the failure onto the Beckn v2.0.0 ErrorCode taxonomy (SCH_INVALID_JSON if body isn't valid JSON, SCH_REQUIRED_FIELD_MISSING if "context" is missing or not an object) so callers can reuse the same Code/Message regardless of how each formats its own response (e.g. wrapping in NewBadReqErr, or writing a bare JSON body directly). req and reqContext are nil on failure. becknErr wraps the underlying json.Unmarshal error for the SCH_INVALID_JSON case (via Error.Unwrap; nil for the missing-context case, which has no cause of its own) — callers that want errors.Is/errors.As to keep reaching it can call errors.As/errors.Is on becknErr directly.
func NewCodedError ¶ added in v1.8.1
NewCodedError constructs an Error carrying an explicit ErrorCode value and message, for callers that already know a specific code to report (e.g. a plugin classifying one of its own failure modes onto the Beckn v2.0.0 ErrorCode taxonomy).
The returned *Error is a plain value, not a step error: nackBecknError (core/module/handler/responsestep.go) only recognizes SchemaValidationErr, CodedErr, AckNoCallbackErr, and any type implementing BecknErrorer. Callers must wrap the result in one of those types (or implement BecknErrorer) before returning it from a Step — returning it bare falls through to a generic 500 Internal Server Error instead of the intended NACK code.
NewCodedErr builds the step error itself, carrying a cause and an HTTP status alongside the code.
func NewCodedErrorWithCause ¶ added in v1.8.1
NewCodedErrorWithCause is like NewCodedError but also records the JSONPath to the failing field (path, may be "") and the underlying cause, so callers don't have to flatten both into the message string to preserve them — Details.Path carries the path and Unwrap() keeps the cause reachable via errors.Is/errors.As.
type ErrorDetails ¶ added in v1.8.1
type ErrorDetails struct {
Path string `json:"path,omitempty"`
Cause *Error `json:"cause,omitempty"`
}
ErrorDetails carries optional structured context for an Error: a JSONPath to the failing field, and/or a chained root-cause Error from a downstream layer.
type Keyset ¶
type Keyset struct {
SubscriberID string
UniqueKeyID string // UniqueKeyID is the identifier for the key pair.
SigningPrivate string // SigningPrivate is the private key used for signing operations.
SigningPublic string // SigningPublic is the public key corresponding to the signing private key.
EncrPrivate string // EncrPrivate is the private key used for encryption operations.
EncrPublic string // EncrPublic is the public key corresponding to the encryption private key.
}
Keyset represents a collection of cryptographic keys used for signing and encryption.
type ManifestDocument ¶ added in v1.6.0
type ManifestDocument struct {
NetworkID string `json:"network_id,omitempty"`
SubscriberID string `json:"subscriber_id,omitempty"`
ContentType string `json:"content_type,omitempty"`
Content []byte `json:"content"`
Digest string `json:"digest"`
SourceURL string `json:"source_url"`
SignatureURL string `json:"signature_url"`
Verified bool `json:"verified"`
FetchedAt time.Time `json:"fetched_at"`
}
ManifestDocument is the cached and returned verified manifest payload.
type ManifestMetadata ¶ added in v1.6.0
type ManifestMetadata struct {
ManifestURL string
ManifestSignatureURL string
SigningPublicKeyLookupURL string
}
ManifestMetadata describes the three inputs needed to fetch and verify a manifest.
type Message ¶
type Message struct {
// Status holds the acknowledgment status (ACK/NACK).
Status Status `json:"status"`
// MessageID echoes the context.messageId from the inbound request.
MessageID string `json:"messageId,omitempty"`
// Error holds error details when Status is NACK.
Error *Error `json:"error,omitempty"`
}
Message represents the synchronous response message envelope (Beckn v2.0.0 LTS shape). The status and messageId are direct fields; the legacy "ack" wrapper is gone. For wire format: {"message":{"status":"ACK","messageId":"<uuid>"}}.
type NetworkManifest ¶ added in v1.6.0
type NetworkManifest struct {
ManifestVersion string `yaml:"manifestVersion"`
ManifestType string `yaml:"manifestType"`
NetworkID string `yaml:"networkId"`
ReleaseID any `yaml:"releaseId"`
Publisher NetworkManifestPublisher `yaml:"publisher"`
Policies *NetworkManifestPolicies `yaml:"policies"`
Governance NetworkManifestGovernance `yaml:"governance"`
}
NetworkManifest is the typed YAML schema for a network-manifest document.
func ParseNetworkManifest ¶ added in v1.6.0
func ParseNetworkManifest(content []byte) (*NetworkManifest, error)
ParseNetworkManifest parses YAML network manifest content.
type NetworkManifestBundle ¶ added in v1.6.0
type NetworkManifestBundle struct {
ID string `yaml:"id"`
URL string `yaml:"url"`
PolicyQueryPath string `yaml:"policyQueryPath"`
Signed bool `yaml:"signed"`
SigningPublicKeyLookupURL string `yaml:"signingPublicKeyLookupUrl"`
}
NetworkManifestBundle describes an OPA bundle policy artifact.
type NetworkManifestFile ¶ added in v1.6.0
type NetworkManifestFile struct {
ID string `yaml:"id"`
URL string `yaml:"url"`
PolicyQueryPath string `yaml:"policyQueryPath"`
Signed bool `yaml:"signed"`
SignatureURL string `yaml:"signatureUrl"`
SigningPublicKeyLookupURL string `yaml:"signingPublicKeyLookupUrl"`
}
NetworkManifestFile describes a single Rego policy artifact.
type NetworkManifestGovernance ¶ added in v1.6.0
type NetworkManifestGovernance struct {
EffectiveFrom string `yaml:"effectiveFrom"`
EffectiveUntil string `yaml:"effectiveUntil"`
Signed *bool `yaml:"signed"`
}
NetworkManifestGovernance describes validity and signature metadata.
type NetworkManifestPolicies ¶ added in v1.6.0
type NetworkManifestPolicies struct {
Type string `yaml:"type"`
Source string `yaml:"source"`
Bundle *NetworkManifestBundle `yaml:"bundle"`
File *NetworkManifestFile `yaml:"file"`
}
NetworkManifestPolicies describes the policy artifact referenced by a network manifest.
type NetworkManifestPublisher ¶ added in v1.6.0
NetworkManifestPublisher identifies the organization publishing the manifest.
type NodeManifest ¶ added in v1.8.0
type NodeManifest struct {
ManifestVersion string `yaml:"manifestVersion"`
ManifestType string `yaml:"manifestType"`
SubscriberID string `yaml:"subscriberId"`
Schema NodeManifestSchema `yaml:"schema"`
Governance NodeManifestGovernance `yaml:"governance"`
}
NodeManifest is the typed YAML schema for a node-manifest document. It is a sibling to NetworkManifest and shares the same DeDi registry placement convention, signing policy, and manifest loader infrastructure.
SubscriberID is the fully-qualified three-part DeDi reference in the format namespace/registry/recordId — e.g. "nfh.global/subscribers.beckn.one/bpp.energy-provider.com". This corresponds to bapId/bppId in the Beckn transaction context.
func ParseNodeManifest ¶ added in v1.8.0
func ParseNodeManifest(content []byte) (*NodeManifest, error)
ParseNodeManifest parses YAML node manifest content.
type NodeManifestGovernance ¶ added in v1.8.0
type NodeManifestGovernance struct {
EffectiveFrom string `yaml:"effectiveFrom"`
EffectiveUntil string `yaml:"effectiveUntil"` // optional — omit for indefinite validity
}
NodeManifestGovernance describes the temporal validity of a node manifest. Unlike NetworkManifestGovernance it carries no Signed field — signature verification is handled by the manifest loader infrastructure.
type NodeManifestSchema ¶ added in v1.8.0
type NodeManifestSchema struct {
DefaultVersionPolicy string `yaml:"defaultVersionPolicy,omitempty"`
SchemaObjects []SchemaObject `yaml:"schemaObjects"`
}
NodeManifestSchema holds the schema capability declarations for a node manifest.
type RegistryMetadata ¶ added in v1.6.0
type RegistryMetadata struct {
NamespaceIdentifier string
RegistryName string
RawMeta map[string]string
}
RegistryMetadata represents metadata configured on a registry itself rather than on a specific record.
type Response ¶
type Response struct {
Message Message `json:"message"`
}
Response represents the main response structure.
type ResponseStepContext ¶ added in v1.7.0
type ResponseStepContext struct {
StatusCode int
Header http.Header // shared reference — step mutations visible to caller
Body []byte // pre-read response body; nil on publisher path
}
ResponseStepContext carries response-phase data for the response step pipeline. It is constructed by the handler from *http.Response before response steps run, keeping transport types out of the ResponseStep interface.
A nil ResponseStepContext signals the publisher path — ONIX writes the ACK itself and there is no upstream response to inspect.
Header is a shared reference to resp.Header; mutations made by steps (e.g. writing the Signature header) are visible to the handler and forwarded by ReverseProxy without any explicit write-back.
type Role ¶
type Role string
Role defines the type of participant in the network.
const ( // RoleBAP represents a Buyer App Participant (BAP) in the network. RoleBAP Role = "bap" // RoleBPP represents a Buyer Platform Participant (BPP) in the network. RoleBPP Role = "bpp" // RoleGateway represents a Gateway that facilitates communication in the network. RoleGateway Role = "gateway" // RoleRegistery represents the Registry that maintains network participant details. RoleRegistery Role = "registery" // RoleDiscovery represents the discovery for that network RoleDiscovery Role = "discovery" )
func (*Role) UnmarshalYAML ¶
UnmarshalYAML implements custom YAML unmarshalling for Role to ensure only valid values are accepted.
type Route ¶
type Route struct {
TargetType string // "url" or "publisher"
PublisherID string // For message queues
URL *url.URL // For API calls
}
Route represents a network route for message processing.
type SchemaObject ¶ added in v1.8.0
type SchemaObject struct {
Type string `yaml:"type"`
BaseURL string `yaml:"baseUrl"`
SupportedVersions []string `yaml:"supportedVersions"`
VersionPolicy string `yaml:"versionPolicy,omitempty"`
PinnedVersion string `yaml:"pinnedVersion,omitempty"`
}
SchemaObject declares the schema types a node supports, with all accepted versions. BaseURL is the base URL prefix shared by all versions (e.g. "https://.../schema/RetailOffer"). SupportedVersions lists every version the app handles natively — payloads at any of these versions are considered compatible without translation. VersionPolicy controls which version is the canonical translation target:
- "latest" (default) — highest version in SupportedVersions
- "pinned" — the explicit PinnedVersion value
Wire format convention: {BaseURL}/{version}/context.jsonld
func (*SchemaObject) CanonicalVersion ¶ added in v1.8.0
func (s *SchemaObject) CanonicalVersion(defaultPolicy string) (string, error)
CanonicalVersion resolves the preferred version for this schema object. defaultPolicy is used when the object's own VersionPolicy is empty; pass manifest.Schema.DefaultVersionPolicy. Falls back to VersionPolicyLatest.
type SchemaValidationErr ¶
type SchemaValidationErr struct {
Errors []Error
}
SchemaValidationErr occurs when schema validation errors are encountered.
func (*SchemaValidationErr) BecknError ¶
func (e *SchemaValidationErr) BecknError() *Error
BecknError converts the SchemaValidationErr to an instance of Error.
func (*SchemaValidationErr) Error ¶
func (e *SchemaValidationErr) Error() string
This implements the error interface for SchemaValidationErr.
type StepContext ¶
type StepContext struct {
context.Context
Request *http.Request
Body []byte
Route *Route
SubID string
Role Role
RespHeader http.Header
ProtocolVersion string // Protocol version parsed from context.version (e.g. "2.0.0")
MessageID string // Message ID parsed from context.messageId in the request body
InboundAuthSignature string // Raw Base64 signature from the inbound Authorization header's signature="..." attribute
IsCallerHandler bool // True when the handler is a Caller (outbound); false for Receiver (inbound)
}
StepContext holds context information for a request processing step.
func (*StepContext) WithContext ¶
func (ctx *StepContext) WithContext(newCtx context.Context)
WithContext updates the existing StepContext with a new context.
type Subscriber ¶
type Subscriber struct {
SubscriberID string `json:"subscriber_id,omitzero"`
URL string `json:"url,omitzero" format:"uri"`
Type string `json:"type,omitzero" enum:"BAP,BPP,BG"`
Domain string `json:"domain,omitzero"`
}
Subscriber represents a unique operational configuration of a trusted platform on a network.
type SubscriberRecord ¶ added in v1.8.0
type SubscriberRecord struct {
Subscription // identity, URL, signing/encryption keys — from data["details"]
Meta map[string]string // node manifest metadata — from data["meta"]; may be empty
}
SubscriberRecord is returned by RegistryMetadataLookup.LookupNode. It carries both the subscriber's identity/endpoint data (from the registry details block) and any node-level manifest metadata (from the registry meta block) in a single response, since both come from the same DeDi endpoint call.
type Subscription ¶
type Subscription struct {
Subscriber `json:",inline"`
KeyID string `json:"key_id,omitzero" format:"uuid"`
SigningPublicKey string `json:"signing_public_key,omitzero"`
EncrPublicKey string `json:"encr_public_key,omitzero"`
ValidFrom time.Time `json:"valid_from,omitzero" format:"date-time"`
ValidUntil time.Time `json:"valid_until,omitzero" format:"date-time"`
Status string `json:"status,omitzero" enum:"INITIATED,UNDER_SUBSCRIPTION,SUBSCRIBED,EXPIRED,UNSUBSCRIBED,INVALID_SSL"`
Created time.Time `json:"created,omitzero" format:"date-time"`
Updated time.Time `json:"updated,omitzero" format:"date-time"`
Nonce string `json:"nonce,omitzero"`
NetworkMemberships []string `json:"network_memberships,omitempty"`
}
Subscription represents subscription details of a network participant.