Audit | Golang SDK
The audit API is designed for recording a trail of application-based user activity in a scalable, tamper-proof log.
OverrideRoots
func (rp *ArweaveRootsProvider) OverrideRoots(roots map[int]Root) map[int]RootUpdateRoots
func (rp *ArweaveRootsProvider) UpdateRoots(ctx context.Context, treeSizes []string) map[int]RootfetchTransaction
func (s *ArweaveRootsProvider) fetchTransaction(ctx context.Context, txID string, target *Root) errorVerifySignature
func (ee *EventEnvelope) VerifySignature() EventVerificationgetPublicKey
func (ee EventEnvelope) getPublicKey() (string, error)String
func (ev EventVerification) String() stringSignEvent
func (i *LogEvent) SignEvent(s signer.Signer, pki map[string]string) errorIsVerifiable
func (event *SearchEvent) IsVerifiable() boolIsVerifiable checks if a record can be verifiable with the published proof
VerifyConsistencyProof
func (ee *SearchEvent) VerifyConsistencyProof(publishedRoots map[int]Root)VerifyMembershipProof
func (ee *SearchEvent) VerifyMembershipProof(root *Root)VerifiableRecords
func (events SearchEvents) VerifiableRecords() SearchEventsVerifiableRecords returns a slice of records that can be verifiable by the published proof
SetTenant
func (e *StandardEvent) SetTenant(tid string)Tenant
func (e *StandardEvent) Tenant() stringDownload search results
func (a *audit) DownloadResults(ctx context.Context, input *DownloadRequest) (*pangea.PangeaResponse[DownloadResult], error)Get all search results as a compressed (gzip) CSV file.
response, err := client.DownloadResults(ctx, &audit.DownloadRequest{
ResultID: "pas_[...]",
Format: audit.DFcsv,
})
Export from the audit log
func (a *audit) Export(ctx context.Context, input *ExportRequest) (*pangea.PangeaResponse[struct{}], error)Bulk export of data from the Secure Audit Log, with optional filtering.
response, err := client.Export(ctx, &audit.ExportRequest{Verbose: pangea.Bool(false)})
Log an entry
func (a *audit) Log(ctx context.Context, event any, verbose bool) (*pangea.PangeaResponse[LogResult], error)Create a log entry in the Secure Audit Log.
event := audit.Event{
Message: "hello world",
}
logResponse, err := auditcli.Log(ctx, event, true)
Log multiple entries
func (a *audit) LogBulk(ctx context.Context, events []any, verbose bool) (*pangea.PangeaResponse[LogBulkResult], error)Create multiple log entries in the Secure Audit Log.
event := audit.Event{
Message: "hello world",
}
events := []audit.Event{event}
logResponse, err := auditcli.LogBulk(ctx, events, true)
Log multiple entries asynchronously
func (a *audit) LogBulkAsync(ctx context.Context, events []any, verbose bool) (*pangea.PangeaResponse[LogBulkResult], error)Asynchronously create multiple log entries in the Secure Audit Log.
event := audit.Event{
Message: "hello world",
}
events := []audit.Event{event}
logResponse, err := auditcli.LogBulkAsync(ctx, events, true)
Log streaming endpoint
func (a *audit) LogStream(ctx context.Context, input pangea.ConfigIDer) (*pangea.PangeaResponse[struct{}], error)This API allows 3rd party vendors (like Auth0) to stream events to this endpoint where the structure of the payload varies across different vendors.
type LogStreamEventData struct {
ClientID string `json:"client_id"`
Connection *string `json:"connection,omitempty"`
ConnectionID *string `json:"connection_id,omitempty"`
Date string `json:"date"`
Description string `json:"description"`
IP string `json:"ip"`
Strategy *string `json:"strategy,omitempty"`
StrategyType *string `json:"strategy_type,omitempty"`
Type string `json:"type"`
UserAgent string `json:"user_agent"`
UserID string `json:"user_id"`
}
type LogStreamEvent struct {
LogID string `json:"log_id"`
Data LogStreamEventData `json:"data"`
}
type LogStreamRequest struct {
pangea.BaseRequest
Logs []LogStreamEvent `json:"logs"`
}
logStreamEvent := LogStreamEvent{
LogID: "some log ID",
Data: LogStreamEventData{
ClientID: "test client ID",
Date: "2024-03-29T17:26:50.193Z",
Description: "Create a log stream",
IP: "127.0.0.1",
Type: "some_type",
UserAgent: "AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.0.0",
UserID: "test user ID",
},
}
input := LogStreamRequest{
Logs: []LogStreamEvent{logStreamEvent},
}
response, err := client.LogStream(ctx, &input)
Tamperproof verification
func (a *audit) Root(ctx context.Context, input *RootInput) (*pangea.PangeaResponse[RootOutput], error)Returns current root hash and consistency proof.
input := &audit.RootInput{
TreeSize: pangea.Int(10),
}
rootResponse, err := auditcli.Root(ctx, input)
Search for events
func (a *audit) Search(ctx context.Context, input *SearchInput) (*pangea.PangeaResponse[SearchOutput], error)Search for events that match the provided search criteria.
input := &audit.SearchInput{
Query: pangea.String("message:log-123"),
IncludeMembershipProof: pangea.Bool(true),
}
searchResponse, err := auditcli.Search(ctx, input)
Search results
func (a *audit) SearchResults(ctx context.Context, input *SearchResultsInput) (*pangea.PangeaResponse[SearchResultsOutput], error)Page through results from a previous search.
input := &audit.SearchResultsInput{
ID: "pas_sqilrhruwu54uggihqj3aie24wrctakr",
}
res, err := auditcli.SearchResults(ctx, input)
fixConsistencyProof
func (a *audit) fixConsistencyProof(ctx context.Context, treeSize int) (map[int]Root, error)getLogBulkRequest
func (a *audit) getLogBulkRequest(events []any, verbose bool) (*LogBulkRequest, error)getLogEvent
func (a *audit) getLogEvent(event any) (*LogEvent, error)getLogRequest
func (a *audit) getLogRequest(event any, verbose bool) (*LogRequest, error)newEventEnvelopeFromMap
func (a *audit) newEventEnvelopeFromMap(m map[string]any) (*EventEnvelope, error)processLogBulkResult
func (a *audit) processLogBulkResult(ctx context.Context, br *LogBulkResult) errorprocessLogResult
func (a *audit) processLogResult(ctx context.Context, log *LogResult) errorprocessSearchEvents
func (a *audit) processSearchEvents(ctx context.Context, events SearchEvents, root *Root, unpRoot *Root) errorType ArweaveRootsProvider
type ArweaveRootsProvider structtype ArweaveRootsProvider struct {
TreeName string
Client *arweave.Arweave
Roots map[int]Root
}
Type Client
type Client interfacetype Client interface {
Log(ctx context.Context, event any, verbose bool) (*pangea.PangeaResponse[LogResult], error)
LogBulk(ctx context.Context, event []any, verbose bool) (*pangea.PangeaResponse[LogBulkResult], error)
LogBulkAsync(ctx context.Context, event []any, verbose bool) (*pangea.PangeaResponse[LogBulkResult], error)
Search(ctx context.Context, req *SearchInput) (*pangea.PangeaResponse[SearchOutput], error)
SearchResults(ctx context.Context, req *SearchResultsInput) (*pangea.PangeaResponse[SearchResultsOutput], error)
Root(ctx context.Context, req *RootInput) (*pangea.PangeaResponse[RootOutput], error)
// Get all search results as a compressed (gzip) CSV file.
DownloadResults(ctx context.Context, input *DownloadRequest) (*pangea.PangeaResponse[DownloadResult], error)
// This API allows 3rd party vendors (like Auth0) to stream events to this
// endpoint where the structure of the payload varies across different
// vendors.
LogStream(ctx context.Context, input pangea.ConfigIDer) (*pangea.PangeaResponse[struct{}], error)
// Bulk export of data from the Secure Audit Log, with optional filtering.
Export(ctx context.Context, input *ExportRequest) (*pangea.PangeaResponse[struct{}], error)
// Base service methods
pangea.BaseServicer
}
Type DownloadFormat
type DownloadFormat stringtype DownloadFormat string
Type DownloadRequest
type DownloadRequest structtype DownloadRequest struct {
pangea.BaseRequest
// ID returned by the export API.
RequestID string `json:"request_id,omitempty"`
// ID returned by the search API.
ResultID string `json:"result_id,omitempty"`
// Format for the records.
Format DownloadFormat `json:"format,omitempty"`
// Return the context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
ReturnContext *bool `json:"return_context,omitempty"`
}
Type DownloadResult
type DownloadResult structtype DownloadResult struct {
// URL where search results can be downloaded.
DestURL string `json:"dest_url"`
}
Type EventEnvelope
type EventEnvelope structtype EventEnvelope struct {
// A structured record describing that <actor> did <action> on <target>
// changing it from <old> to <new> and the operation was <status>,
// and/or a free-form <message>.
Event any `json:"event"`
// An optional client-side signature for forgery protection.
// max len of 256 bytes
Signature *string `json:"signature,omitempty"`
// The base64-encoded ed25519 public key used for the signature, if one is provided
PublicKey *string `json:"public_key,omitempty"`
// A server-supplied timestamp.
ReceivedAt *pu.PangeaTimestamp `json:"received_at,omitempty"`
}
Type EventVerification
type EventVerification inttype EventVerification int
Type ExportRequest
type ExportRequest structtype ExportRequest struct {
pangea.BaseRequest
// Format for the records.
Format *DownloadFormat `json:"format,omitempty"`
// The start of the time range to perform the search on.
Start *string `json:"start,omitempty"`
// The end of the time range to perform the search on. If omitted, then all
// records up to the latest will be searched.
End *string `json:"end,omitempty"`
// Specify the sort order of the response, "asc" or "desc".
Order *string `json:"order,omitempty"`
// Name of column to sort the results by.
OrderBy *string `json:"order_by,omitempty"`
// Whether or not to include the root hash of the tree and the membership
// proof for each record.
Verbose *bool `json:"verbose,omitempty"`
}
Type LogBulkRequest
type LogBulkRequest structtype LogBulkRequest struct {
// Base request has ConfigID for multi-config projects
pangea.BaseRequest
Events []*LogEvent `json:"events"`
// If true, be verbose in the response; include root, membership and consistency proof, etc.
// default: false
Verbose bool `json:"verbose"`
}
Type LogBulkResult
type LogBulkResult structtype LogBulkResult struct {
Results []LogResult `json:"results"`
}
Type LogEvent
type LogEvent structtype LogEvent struct {
// A structured event describing an auditable activity.
Event any `json:"event"`
// An optional client-side signature for forgery protection.
// max len of 256 bytes
Signature *string `json:"signature,omitempty"`
// The base64-encoded ed25519 public key used for the signature, if one is provided
PublicKey *string `json:"public_key,omitempty"`
}
Type LogRequest
type LogRequest structtype LogRequest struct {
// Base request has ConfigID for multi-config projects
pangea.BaseRequest
LogEvent
// If true, be verbose in the response; include root, membership and consistency proof, etc.
// default: false
Verbose bool `json:"verbose"`
// Previous unpublished root
PrevRoot *string `json:"prev_root,omitempty"`
}
Type LogResult
type LogResult structtype LogResult struct {
EventEnvelope *EventEnvelope
RawEnvelope map[string]any `json:"envelope"`
// The hash of the event data.
// max len of 64 bytes
Hash string `json:"hash"`
UnpublishedRootHash *string `json:"unpublished_root,omitempty"`
MembershipProof *string `json:"membership_proof,omitempty"`
ConsistencyProof *[]string `json:"consistency_proof,omitempty"`
MembershipVerification EventVerification
ConcistencyVerification EventVerification
SignatureVerification EventVerification
}
Type LogSigningMode
type LogSigningMode inttype LogSigningMode int
Type Option
type Option func(*audit) errortype Option func(*audit) error
Type Root
type Root structtype Root struct {
// The name of the Merkle Tree
TreeName string `json:"tree_name"`
// The size of the tree (the number of records)
Size int `json:"size"`
// The root hash
// max len of 64 bytes
RootHash string `json:"root_hash"`
// The URL where this root has been published
URL *string `json:"url"`
// The date/time when this root was published
PublishedAt *time.Time `json:"published_at"`
// Consistency proof to verify that this root is a continuation of the previous one
ConsistencyProof *[]string `json:"consistency_proof"`
}
Type RootInput
type RootInput structtype RootInput struct {
// Base request has ConfigID for multi-config projects
pangea.BaseRequest
// The size of the tree (the number of records)
TreeSize int `json:"tree_size,omitempty"`
}
Type RootOutput
type RootOutput structtype RootOutput struct {
Data Root `json:"data"`
}
Type RootsProvider
type RootsProvider interfacetype RootsProvider interface {
UpdateRoots(ctx context.Context, treeSizes []string) map[int]Root
OverrideRoots(roots map[int]Root) map[int]Root
}
Type SearchEvent
type SearchEvent structtype SearchEvent struct {
// Include Event data and security information
EventEnvelope *EventEnvelope
RawEnvelope map[string]any `json:"envelope"`
// The record's hash
// len of 64 bytes
Hash string `json:"hash"`
// The index of the leaf of the Merkle Tree where this record was inserted.
LeafIndex *int `json:"leaf_index"`
// A cryptographic proof that the record has been persisted in the log.
MembershipProof *string `json:"membership_proof"`
Published *bool `json:"published"`
MembershipVerification EventVerification
ConsistencyVerification EventVerification
SignatureVerification EventVerification
// The context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
FPEContext *string `json:"fpe_context,omitempty"`
}
Type SearchEvents
type SearchEvents []*SearchEventtype SearchEvents []*SearchEvent
Type SearchInput
type SearchInput structtype SearchInput struct {
// Base request has ConfigID for multi-config projects
pangea.BaseRequest
// Natural search string; list of keywords with optional `<option>:<value>` qualifiers.
//
// Query is a required field.
//
// The following optional qualifiers are supported:
// * action:
// * actor:
// * message:
// * new:
// * old:
// * status:
// * target:
//
// examples:
// actor:root target:/etc/shadow
Query string `json:"query"`
// Specify the sort order of the response. "asc" or "desc"
Order string `json:"order,omitempty"`
// Name of column to sort the results by.
OrderBy string `json:"order_by,omitempty"`
// The start of the time range to perform the search on.
Start *time.Time `json:"start,omitempty"`
// The end of the time range to perform the search on. All records up to the latest if left out.
End *time.Time `json:"end,omitempty"`
// Number of audit records to include from the first page of the results.
Limit int `json:"limit,omitempty"`
// Maximum number of results to return.
// min 1 max 10000
MaxResults int `json:"max_results,omitempty"`
// If true include root, membership and consistency proof
Verbose *bool `json:"verbose,omitempty"`
// A list of keys to restrict the search results to. Useful for partitioning data available to the query string.
SearchRestriction *SearchRestriction `json:"search_restriction,omitempty"`
// Return the context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
ReturnContext *bool `json:"return_context,omitempty"`
}
Type SearchOutput
type SearchOutput structtype SearchOutput struct {
// Identifier to supply to search_results API to fetch/paginate through search results.
// ID is always populated on a successful response.
ID string `json:"id"`
// The time when the results will no longer be available to page through via the results API.
// ExpiresAt is always populated on a successful response.
ExpiresAt *time.Time `json:"expires_at"`
// The total number of results that were returned by the search.
// Count is always populated on a successful response.
Count int `json:"count"`
// A list of matching audit records.
// Events is always populated on a successful response.
Events SearchEvents `json:"events"`
// A root of a Merkle Tree
Root *Root `json:"root,omitempty"`
// A unpublished root of a Merkle Tree
UnpublishedRoot *Root `json:"unpublished_root,omitempty"`
}
Type SearchRestriction
type SearchRestriction structtype SearchRestriction struct {
// A list of actors to restrict the search to.
Actor []string `json:"actor,omitempty"`
// A list of sources to restrict the search to.
Source []string `json:"source,omitempty"`
// A list of targets to restrict the search to.
Target []string `json:"target,omitempty"`
// A list of actions to restrict the search to.
Action []string `json:"action,omitempty"`
// A list of statuses to restrict the search to.
Status []string `json:"status,omitempty"`
}
Type SearchResultsInput
type SearchResultsInput structtype SearchResultsInput struct {
// Base request has ConfigID for multi-config projects
pangea.BaseRequest
// A search results identifier returned by the search call
// ID is a required field
ID string `json:"id"`
// Number of audit records to include from the first page of the results.
Limit int `json:"limit,omitempty"`
// Offset from the start of the result set to start returning results from.
Offset *int `json:"offset,omitempty"`
// If provided, fail if the original search was performed with anything but the provided search_restriction parameter.
AssertSearchRestriction *SearchRestriction `json:"assert_search_restriction,omitempty"`
// Return the context data needed to decrypt secure audit events that have been redacted with format preserving encryption.
ReturnContext *bool `json:"return_context,omitempty"`
}
Type SearchResultsOutput
type SearchResultsOutput structtype SearchResultsOutput struct {
// The total number of results that were returned by the search.
// Count is always populated on a successful response.
Count int `json:"count"`
// A list of matching audit records.
// Events is always populated on a successful response.
Events SearchEvents `json:"events"`
// A root of a Merkle Tree
Root *Root `json:"root"`
// A unpublished root of a Merkle Tree
UnpublishedRoot *Root `json:"unpublished_root"`
}
Type StandardEvent
type StandardEvent structtype StandardEvent struct {
// Record who performed the auditable activity.
// max len is 128 bytes
// examples:
// John Doe
// user-id
// DennisNedry@InGen.com
Actor string `json:"actor,omitempty"`
// The auditable action that occurred."
// max len is 32 bytes
// examples:
// created
// deleted
// updated
Action string `json:"action,omitempty"`
// A message describing a detailed account of what happened.
// This can be recorded as free-form text or as a JSON-formatted string.
// Message is a required field.
// max len of 65536 bytes
Message string `json:"message"`
// The value of a record after it was changed.
// max len of 65536 bytes
New string `json:"new,omitempty"`
// The value of a record before it was changed.
// max len of 65536 bytes
Old string `json:"old,omitempty"`
// Used to record the location from where an activity occurred.
// max len of 128 bytes
Source string `json:"source,omitempty"`
// Record whether or not the activity was successful.
// examples:
// failure
// success
// max len of 32 bytes
Status string `json:"status,omitempty"`
// Used to record the specific record that was targeted by the auditable activity.
// max len of 128 bytes
Target string `json:"target,omitempty"`
// An optional client-supplied timestamp.
Timestamp *pu.PangeaTimestamp `json:"timestamp,omitempty"`
// TenantID field
TenantID string `json:"tenant_id,omitempty"`
}
Type Tenanter
type Tenanter interfacetype Tenanter interface {
Tenant() string
SetTenant(string)
}
Type ValidateEvents
type ValidateEvents []*ValidatedEventtype ValidateEvents []*ValidatedEvent
Type ValidatedEvent
type ValidatedEvent structtype ValidatedEvent struct {
// the event that was validated
Event *EventEnvelope
// True if the event was successfully validated nil if there is no membership to validate
MembershipProofStatus *bool
// True if the event was successfully validated nil if there is no hash to validate
ConsistencyProofStatus *bool
}
Type audit
type audit structtype audit struct {
pangea.BaseService
signer *signer.Signer
verifyProofs bool
skipEventVerification bool
publicKeyInfo map[string]string
rp RootsProvider
lastUnpRootHash *string
tenantID string
schema any
}
Type proof
type proof []proofItemtype proof []proofItem
Type proofItem
type proofItem structtype proofItem struct {
Side proofSide
Hash hash.Hash
}
Type proofSide
type proofSide uinttype proofSide uint
Type rootProof
type rootProof []rootProofItemtype rootProof []rootProofItem
Type rootProofItem
type rootProofItem structtype rootProofItem struct {
Hash hash.Hash
Proof proof
}