Disabling a service/intercept for specific idenities

Hello,

I’m making a web interface for OpenZiti and I would like to have the ability to enable and disable services for identities. First I tried just removing the role allowing the identity to dial the service, but after adding the dial role back to the identity the intercept doesn’t work. To fix this the user has to restart the identities connection to the Ziti fabric. Is there another way to do this, or is this a bug that will be fixed in the future?

Thanks!

The edge tunnelers I tested this on were the Ziti Desktop Edge for MacOS and the Android Tunneler

That sounds neat! I think you want a simplified GUI for managing all of the Ziti Identities in a Ziti Network, specifically for toggling the availability for a specific Ziti Service on each identity. Is that right?

For example, if I’m looking at one of my identities in this UI, I can see all the services that are assigned to the identity and toggle them individually. Disabling a particular service doesn’t cause the network to “forget” it was previously authorized. It’s still in the list of services, and I can re-enable it with a click.


With that clarified goal in mind, the specific problem you encountered is that some running tunneler didn’t notice it had become authorized to dial a service. You worked around the problem by restarting the tunneler.

It’s not a known problem, no, and needing to restart the tunneler is unexpected. There’s a Ziti Tunneler available for all of the supported operating systems, and they periodically update their internal directory of available services and configure the OS accordingly (DNS, routes, etc).

Let’s figure out precisely why it’s not working. I assume you’re hosting the network controller.

  1. Which tunneler on which OS? - ZDE for macOS and ZME for Android
  2. Did you customize the tunneler or the configuration, e.g. the polling interval?
  3. Did you ensure there are no tunneler app updates available?
  4. What version is your Ziti Network?
  5. Is your Ziti Network in clustered or standalone mode?
  6. What specific technique did you use to toggle authorization, adding and removing the identity’s role attribute, e.g., #dialers?
  7. During the unexpected problem time frame, when the identity is authorized yet cannot use the service, did you confirm via the API or CLI (removing the developing UI from the equation) that the expected state is in effect, e.g., that the role was correctly added? You can verify the identity is currently authorized by running ziti edge policy-advisor.
  8. Did you allow at least 60s to pass after authorizing the identity to use the service? I believe most tunnelers update their service list every few seconds (default: 15s).
  9. Crucially, what is the specific symptom that occurs when the “intercept doesn’t work?” For example, the Android app that’s failing to use the Ziti Service may have succeeded in resolving the domain name, and yet attempting to open a TCP stream gets “connection refused.”
  10. Does the dialing tunneler’s log show the expected service was, indeed, authorized after centrally, administratively re-authorizing the service?

The idea behind my project is to create a self-hosted, multi-tenant service access and sharing platform powered by OpenZiti. It wraps the OpenZiti controller in an easy-to-use UI, allowing users to create and share services between accounts.

Each user can have multiple identities, which correspond directly to Ziti identities. Sharing a service grants all the recipient’s identities a role on the OpenZiti controller, allowing them to dial the service owned and controlled by another user.

The service owner should be able to enable or disable a service at any time via a UI button, which will remove the dial role for that service from all identities. In the future, I plan to implement fine-grained control over each identity’s access to services by dynamically adding or removing dial roles.

For more information on my project, see tunnl.app.

Issue description
When my edge tunneler (ZDE for macOS) has the role allowing it to dial a service, it works as expected. However, after:

  1. Dialing the service at least once on my Mac,

  2. Removing the dial attribute from the identity,

  3. Waiting until the service dial disappears from the services list in ZDE for macOS,

  4. Adding the dial attribute back to the identity,

  5. Waiting until the service dial reappears in the services list in ZDE for macOS,

attempting to dial the service again using the same intercept configuration fails.

Once I restart the edge tunneler, the service can be dialed successfully again.

From the logs, after the service dial role is re-added and appears in the ZDE for macOS UI, it seems the tunneler detects that I’m trying to dial an OpenZiti service, but the connection attempt fails.

Here’s the section I was watching, full logs are at https://pastebin.com/raw/7UvWNZUJ

(7729)\[2025-08-09T17:15:17.603Z\]   DEBUG ziti-sdk:connect.c:550 process_connect() conn0.16/cGVlFfMM/Connecting starting Dial connection for service\[portfolio-o2ni0n0dwfkk-UTLcGAGlOnMO\] with session\[cme4ildtx18ezp20lqapv9m3p\]
(7729)\[2025-08-09T17:15:17.603Z\]   DEBUG ziti-sdk:connect.c:409 ziti_connect() conn0.16/cGVlFfMM/Connecting selected ch\[tunnl-tester-edge-router@tls://er1.ziti.mesh.ahop.dev:443\] for best latency(58 ms)
(7729)\[2025-08-09T17:15:17.603Z\]   TRACE ziti-sdk:connect.c:1123 ziti_channel_start_connection() conn0.16/cGVlFfMM/Connecting ch\[0\] => Edge Connect request token\[f0b33bc8-6276-45cb-afaa-31071fcebe84\]
(7729)\[2025-08-09T17:15:17.603Z\]   DEBUG ziti-sdk:channel.c:238 ziti_channel_add_receiver() ch\[0\] added receiver\[16\]
(7729)\[2025-08-09T17:15:17.603Z\]   TRACE ziti-sdk:channel.c:435 ziti_channel_send_message() ch\[0\] => ct\[ConnectType\] seq\[45\] len\[36\]
(7729)\[2025-08-09T17:15:17.603Z\]   TRACE ziti-sdk:channel.c:405 on_channel_send() ch\[0\] write delay = 0.000d q=1 qs=347
(7729)\[2025-08-09T17:15:17.603Z\]   TRACE tunnel-sdk:ziti_tunnel.c:516 check_lwip_timeouts() next wake in 65 millis
(7729)\[2025-08-09T17:15:17.669Z\]   TRACE tunnel-sdk:ziti_tunnel.c:516 check_lwip_timeouts() next wake in 250 millis
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:937 on_channel_data() ch\[0\] on_data \[len=129\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:615 process_inbound() ch\[0\] <= ct\[StateClosedType\] seq\[48\] len\[14\] hdrs\[24\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:625 process_inbound() ch\[0\] completing msg seq\[48\] body+hrds=14+24, in_offset=0, want=38, got=38
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:639 process_inbound() ch\[0\] message is complete seq\[48\] ct\[StateClosedType\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:91 parse_hdrs() parsing headers len\[24\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:104 parse_hdrs() hdr\[0\] id\[1000\] len\[4\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:104 parse_hdrs() hdr\[1\] id\[1001\] len\[4\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:connect.c:810 flush_connection() conn0.16/cGVlFfMM/Connecting starting flusher
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:615 process_inbound() ch\[0\] <= ct\[StateClosedType\] seq\[49\] len\[15\] hdrs\[36\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:625 process_inbound() ch\[0\] completing msg seq\[49\] body+hrds=15+36, in_offset=0, want=51, got=51
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:639 process_inbound() ch\[0\] message is complete seq\[49\] ct\[StateClosedType\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:91 parse_hdrs() parsing headers len\[36\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:104 parse_hdrs() hdr\[0\] id\[1000\] len\[4\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:104 parse_hdrs() hdr\[1\] id\[1001\] len\[4\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:message.c:104 parse_hdrs() hdr\[2\] id\[1\] len\[4\]
(7729)\[2025-08-09T17:15:17.749Z\]   ERROR ziti-sdk:connect.c:1070 connect_reply_cb() conn0.16/cGVlFfMM/Connecting failed to connect, reason=invalid session
(7729)\[2025-08-09T17:15:17.749Z\] VERBOSE ziti-sdk:connect.c:129 conn_set_state() conn0.16/cGVlFfMM/Connecting transitioning Connecting => Disconnected
(7729)\[2025-08-09T17:15:17.749Z\]   DEBUG ziti-sdk:connect.c:323 complete_conn_req() conn0.16/cGVlFfMM/Disconnected Disconnected failed: connection is closed
(7729)\[2025-08-09T17:15:17.749Z\] VERBOSE ziti-sdk:connect.c:129 conn_set_state() conn0.16/cGVlFfMM/Disconnected transitioning Disconnected => Disconnected
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:461 ziti_channel_send() ch\[0\] => ct\[StateClosedType\] seq\[46\] len\[0\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:435 ziti_channel_send_message() ch\[0\] => ct\[StateClosedType\] seq\[46\] len\[0\]
(7729)\[2025-08-09T17:15:17.749Z\]   TRACE ziti-sdk:channel.c:405 on_channel_send() ch\[0\] write delay = 0.000d q=1 qs=32
(7729)\[2025-08-09T17:15:17.749Z\] VERBOSE tunnel-cbs:ziti_tunnel_cbs.c:93 on_ziti_connect() on_ziti_connect status: -24
(7729)\[2025-08-09T17:15:17.749Z\]   ERROR tunnel-cbs:ziti_tunnel_cbs.c:103 on_ziti_connect() ziti dial failed: connection is closed
(7729)\[2025-08-09T17:15:17.749Z\] VERBOSE ziti-sdk:connect.c:129 conn_set_state() conn0.16/cGVlFfMM/Disconnected transitioning Disconnected => Closed

To answer your questions directly

  1. I did an in depth investigation into the issue on ZDE for macOS
  2. My Ziti Desktop Edge Config has the settings
    IPv4 Address: 203.0.113.0
    Subnet Mask: 255.255.255.0
    MTU: 1500
    DNS Server: 203.0.113.1
    No Override Fallback DNS
    Yes to Intercept DNS by Matching Domains
  3. As of Aug 9th I see no updates available in the App Store for MacOS
  4. v1.5.4 installed with the quickstart script
  5. Standalone
  6. I added and removed the identities dial attribute via the management API, your example of using #dialers is correct.
  7. While having the issue ziti edge policy-advisor identities returns
OKAY : macbook-pro-zOdT8gFblUq7 (1) -> portfolio-o2ni0n0dwfkk-UTLcGAGlOnMO (1) Common Routers: (1/1) Dial: Y Bind: Y
  1. I tried waiting for 60s and I still had the issue.
  2. After further investigation it seems the edge tunneler is identifying when a DNS lookup is for a Ziti intercept, but fails to connect to the service. It may have something to do with Connecting failed to connect, reason=invalid session.
  3. The log does show the service was authorized.
1 Like

I went through the steps to produce the issue over an hour ago but I haven’t restarted ZDE for macOS, and I’m still failing to connect to the service.

I tested the ziti-edge-tunnel binary on Linux amd64 and the issue did not occur.

I also tested ZME for Android and the issue did occur

It seems unlikely, but there is an unusual condition that can cause the invalid session error. Do you happen to have a restrictive Service Edge Router Policy (SERP) or using the default, permissive SERP of #all/#all?

Also, did you test on Linux with the same service? If so, is the Linux device also running any other Ziti software involved in that service, like one of the authorized routers?

Another macOS user and myself, with Android ZME, both encountered the same symptom: the service didn’t recover when the dialing role was re-added to the identity.