# Levitron Milestone: Decentralized API Boundary Node Access Logs

**URL:** <https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773>\
**Category:** Developers\
**Tags:** Boundary-nodes\
**Created:** [July 24, 2025, 9:21am UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773 "2025-07-24T09:21:29Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![rbirkner](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@rbirkner](https://forum.dfinity.org/u/rbirkner)\
**Post date:** [July 24, 2025, 9:21am UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/1 "2025-07-24T09:21:29Z")

</div>

Hello everyone,

We, the boundary node team, are excited to announce a step forward in transparency and insights for you guys, the Internet Computer community! With the completion of the Levitron milestone, we are making the API Boundary Node (API BN) access logs publicly available in real-time.

 ![access-logs](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/f/a/facb61434a266514ecd647edc4a6f2534e2294c1.png)

This means you can now get visibility into how the Internet Computer and its canisters are being used. These logs offer new insights into canister usage, daily active users, and temporal behavior.

The key highlights are:

- _Real-time and decentralized access:_ stream the access logs directly from the API BNs without any intermediary.
- _Privacy-preserving:_ logs include client IDs (salted hashes) but no sensitive user data like IP addresses or sender principals.
- _Future authenticity:_ upcoming SEV-SNP-enabled API BNs will allow clients to attest to the logs’ integrity.

Start streaming logs immediately and build your own storage for historical data.

Ready to dive in?

- Learn more in the full blog post: [medium/dfinity](https://medium.com/dfinity/real-time-transparency-with-public-api-boundary-node-access-logs-5ecf0a5017fe)
- Get started with the [developer documentation](https://internetcomputer.org/docs/building-apps/advanced/canister-access-logs)
- Explore the sample client: [dfinity/ic-bn-logs](https://github.com/dfinity/ic-bn-logs)

We believe this will be a great resource for developers and anyone interested in understanding the Internet Computer’s activity. Let us know what insights you discover!

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [July 24, 2025, 12:57pm UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/2 "2025-07-24T12:57:44Z")

</div>

I’d like to just take a moment to appreciate that DFINITY still does this work. I doubt many people were clamoring for this, but it is so important for the long-term transparency of how the IC operates. Amazing work!

Quick question…if we analyze these logs and find a salt that is a little chatty, do we have the salting algo that we can use on the canister side to block it(or use it in motoko for our `inspect` functions?) I guess that might reveal the info. Perhaps there is room to pass it in at the system level somehow? I guess it also depends on how stable the clientIds are.(what is used to produce them?)

---

<div class="post-metadata">

**Author:** ![rbirkner](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@rbirkner](https://forum.dfinity.org/u/rbirkner)\
**Post date:** [July 24, 2025, 1:27pm UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/3 "2025-07-24T13:27:33Z")

</div>

Hey @skilesare

We really appreciate the kind words, they mean a lot to us!

About the salt and the client id:  
The client id is computed by concatenating the sender principal and the client IP address, then hashing it with a secret salt (using SHA3-256), and finally taking the first 16 bytes of the result.

The salt comes from the [“salt-sharing” canister](https://dashboard.internetcomputer.org/canister/uz2z3-qyaaa-aaaaq-qaacq-cai), which only allows API BNs to fetch the salt and rotates it every month.

Even if you knew the salt, it would be extremely difficult for you to “revert” the client IDs back to the sender principal and client IP. You could try to build a rainbow table, but the “input space” is just way too huge (prinicipals can have up to 29 bytes and IP addresses up to 16 bytes for IPv6).

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [July 24, 2025, 5:55pm UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/4 "2025-07-24T17:55:14Z")

</div>

Great milestone, BN team, congratulations! 🎉

This doesn’t require an answer, but just in case someone happens to known:

I tried to vibe code a web app using Windsurf (as I’m currently testing [Juno’s LLM documentation](https://juno.build/docs/guides/ai)) and those WebSockets. As a starting point, I used the [Rust example](https://github.com/dfinity/ic-bn-logs/blob/main/src/main.rs) you provided and asked the AI to translate it for the frontend. However, it struggled with converting the `fetch_api_boundary_nodes_by_subnet_id` function from the Agent to JS code. Fair enough, I don’t know the answer either 😄.

So just out of curiosity, I was wondering if that call exist in the frontend environment too? Is it somehow exposed by Agent-js?

Again, really no need to dig into it only if someone knows off the top of their head. It was more an experiment that an important task.

---

<div class="post-metadata">

**Author:** ![rbirkner](https://avatars.discourse-cdn.com/v4/letter/r/838e76/32.png) [@rbirkner](https://forum.dfinity.org/u/rbirkner)\
**Post date:** [July 24, 2025, 7:53pm UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/5 "2025-07-24T19:53:46Z")

</div>

Hey @peterparker

`fetch_api_boundary_nodes_by_subnet_id` is simply a convenience function for requesting a specific path using a `read_state`.

All the API boundary nodes are listed under `/api_boundary_nodes` in the system state tree: You can find the domain, IPv4 and IPv6 address:

```auto
/api_boundary_nodes/<node_id>/domain
/api_boundary_nodes/<node_id>/ipv4_address
/api_boundary_nodes/<node_id>/ipv6_address

```

The `by_subnet_id` part is just needed to route the `read_state` to a replica and the `by_canister_id` equivalent exists as well: You can specify any subnet ID or any canister ID and you will get an answer 🙂

---

<div class="post-metadata">

**Author:** ![peterparker](https://avatars.discourse-cdn.com/v4/letter/p/b9bd4f/32.png) [@peterparker](https://forum.dfinity.org/u/peterparker)\
**Post date:** [July 25, 2025, 4:57am UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/6 "2025-07-25T04:57:36Z")

</div>

Nice, thanks for the explanation!

I tried feeding your answer to Windsurf. It started off well, understanding that it had to use Agent-js for the lookup and certificate, but it didn’t manage to implement it. Just an experiment, I spent a few minutes trying to guide it but ultimately gave up. Really good to know nonetheless!

---

<div class="post-metadata">

**Author:** ![quint](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/quint/32/40449_2.png) [@quint](https://forum.dfinity.org/u/quint)\
**Post date:** [August 7, 2025, 6:31am UTC](https://forum.dfinity.org/t/levitron-milestone-decentralized-api-boundary-node-access-logs/53773/7 "2025-08-07T06:31:42Z")

</div>

Thanks Rüdiger, this is a wonderful feature! ⭐  
I already started playing around and building some dashboards on this data!

 ![image](https://us1.discourse-cdn.com/flex023/uploads/dfn/original/3X/a/b/abfc071ce5716987dcc9c380f99eadef2fb84812.png)
