--- title: "Auditing Messages from Cross Account/External/Managed Apps" slug: "auditing-messages-from-cross-accountexternalmanaged-apps" updated: 2022-06-01T23:15:37Z published: 2022-06-01T23:15:37Z canonical: "docs.echo.stream/auditing-messages-from-cross-accountexternalmanaged-apps" --- > ## Documentation Index > Fetch the complete documentation index at: https://docs.echo.stream/llms.txt > Use this file to discover all available pages before exploring further. # Auditing Messages from Cross Account/External/Managed Apps Auditing of messages in the EchoStream Cloud is done automatically for you every time a message arrives at a Node. For those Nodes that are external to the EchoStream Cloud ([External Nodes](/v1/docs/external-nodes)). Since you provide the code that implements these Nodes, you are responsible for auditing messages (if you wish) when they received or when you are about to send them. ## Auditing using the `echostream-node` package External Nodes that you choose to implement in Python can rely on the [echostream-node](/v1/docs/echostream-node-package) package to help them perform auditing. To perform this, simply call the `audit_message` or `audit_messages` method on the Node object ([threading](https://docs.echostream-node.echo.stream/echostream_node/threading.html#Node.audit_message) or [asycnio](https://docs.echostream-node.echo.stream/echostream_node/asyncio.html#Node.audit_message)). Auditing provided by this package will automatically queue your audit messages and concurrently tsend them to the EchoStream Cloud for your Node. ``` from echostream_node import Message from echostream_node.threading import AppNode class MyNode(AppNode): def handle_received_message(self, *, message: Message, source: str) -> None: self.audit_message(message, source=source) ``` > NOTE - this is the recommended method for both implementing External Nodes and for auditing messages processed by those Nodes. ## Auditing without use of the `echostream-node` package If you choose to implement your External Node in a lamguage other than Python or you choose not to use the `echostream-node` package, then you must interact with your App's Audit Records Endpoint directly. ### Audit Records Endpoint The Audit Records Endpoint is a RESTful API endpoint that exposes a single API. This API requires that: - You call it with your External Node's name as the path ``` https://.lambda-url..on.aws/my-node-name ``` - Only accepts POST requests - Takes a JSON payload (which may be GZIP'd) ``` { "messageType": "echo.text", # The name of the EchoStream message type for the auditRecords "auditRecords": [ # A list of the audited records, one per message { "attributes": {...}, # A flat dictionary of string keys and and any scalar value for the message "datetime": "2022-06-01T22:50:34.696331+00:00", # The datetime of the audit, in ISO 8601 format "previousTrackingIds": [ # A list of previous tracking IDs for the message (optional) "5a16bbad91e1470a9e67098c8f91dd12", ... ], "sourceNode": "SendingNode", # The name of the Node that sent you the message (optional) "trackingId": "5a638b9c84e546b288e351a0d2537fc4" # The tracking ID of the message }, ... ] } ``` ### Using the Audit Records Endpoint 1. Get your App's AWS Credentials by calling `GetApp.GetAwsCredentials` 2. Get your App's Audit Records Endpoint by calling `GetApp.auditRecordsEndpoint` 3. Using the credentials from step #1, construct a [SignatureV4 Authorization](https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html) Token, using `lambda` as the `aws-service` 1. Place the resulting token in the `Authorization` header 2. Place the Session token (from step #1) in the `x-amz-security-token` header 3. Place the hash of the body in the `x-amz-content-sha256` header 4. Place the date of the request in the `x-amz-date` header 4. POST the request to the endpoint from step #2, using your Node's name as the path (be sure to URL-encode the name!) The endpoint will return a `201` upon success, with the following JSON payload ``` { "app": "YourApp", # the name of the app the records were recorded for "messageType": "echo.text", # the message type used in the audit records "node": "YourNode", # the name of the node the records were recorded for "recordsProcessed": 20, # the number of audit records that were processed "tenant": "YourTenant" # the name of the tenant the records were recorded for } ```