
OpenZiti C SDK

The OpenZiti C SDK allows developers to create their own custom OpenZiti network endpoint applications.
OpenZiti is a modern, programmable network overlay with associated edge components, for application-embedded, zero trust network connectivity, written by developers for developers. The SDK harnesses that power via APIs that allow developers to imagine and develop solutions beyond what OpenZiti handles by default.
This SDK does the following:
- enable network endpoint clients allow a device to dial (access) or bind (host) OpenZiti Services
- provides authentication interfaces for x509 certificates flows
- collects and submits security posture collection/submission for Posture Checks
- allows applications to bind or dial services via standard `socket` interfaces
Configuring Your Application to use OpenZiti C SDK
The easiest way to embed Ziti SDK in your app is to pull the project into your CMake build
FetchContent_Declare(ziti-sdk-c
GIT_REPOSITORY https://github.com/openziti/ziti-sdk-c.git
GIT_TAG ${LATEST_ZITI_RELEASE}
)
FetchContent_MakeAvailable(ziti-sdk-c)
# ...
# ...
add_executable(most-secure-app-ever ${my_sources})
target_link_libraries(most-secure-app-ever PRIVATE ziti)
You will also need other libraries that OpenZiti SDK uses (they are specified in vcpkg.json):
library | usage |
libuv | event loop |
openssl | TLS |
zlib | HTTPS compression |
llhttp | HTTP parsing |
libsodium | OpenZiti end-to-end encryption |
There are multiple ways to get those 3rd party dependencies into your build: system level, CMake FetchContent
, vcpkg, etc. We recommend using vcpkg
.
If you want to contribute/build/hack this SDK in standalone mode see the BUILD.md for information on how to do it.
Using OpenZiti in Your Application
High-Level (<tt>Zitilib</tt>) API
The high-level API was developed to simplify embedding OpenZiti in an application. The main feature of this API is presenting Ziti connections as regular socket file descriptors (or handles on Windows). These sockets can be used both blocking and non-blocking modes.
SDK Initialization and Teardown
There are just three functions that cover SDK initialization and teardown. Additional steps may be required to complete authentication. See example below.
int main(int argc, char *argv[]) {
const char *identity_file = process_args(argc, argv);
if (err ==
ZITI_OK)
goto important_work;
const char *singer = ...;
}
char *code = ...;
}
fprintf(stderr, "Failed to load identity: %s\n", Ziti_strerror(rc));
}
important_work:
...
}
#define ZITI_EXTERNAL_LOGIN_REQUIRED
returned when an external login is required to complete authentication
Definition errors.h:117
#define ZITI_OK
The expected outcome of a successful operation.
Definition errors.h:33
#define ZITI_PARTIALLY_AUTHENTICATED
returned when authentication is attempted but there is an existing api session waiting for auth queri...
Definition errors.h:101
Definition ziti_model.h:268
uint32_t ziti_handle_t
Definition zitilib.h:31
ziti_jwt_signer_array Ziti_get_ext_signers(ziti_handle_t ztx)
Get external signers available for authentication.
int Ziti_wait_for_auth(ziti_handle_t ztx, int timeout_ms)
Wait for authentication to complete.
int Ziti_load_context(ziti_handle_t *h, const char *identity)
Load Ziti identity.
char * Ziti_login_external(ziti_handle_t ztx, const char *signer_name)
Start external login process.
void Ziti_lib_init(void)
Initialize Ziti library.
void Ziti_lib_shutdown(void)
Shutdown Ziti library.
int Ziti_login_totp(ziti_handle_t ztx, const char *code)
Login with TOTP code.
Once ziti_context
is loaded it can be used to dial a service or bind to a service (provided the identity has proper access to it).
Dialing a service
function | usage |
Ziti_connect(sock, ztx, service, terminator) | connects given socket to the service/terminator within the context |
Ziti_connect_addr(sock, hostname, port) | connects given socket to the specified intercept address |
int error =
Ziti_connect(sock, ztx,
"my-secure-service", NULL);
do {
write(sock, ...);
read(sock, ...);
} while (!done);
close(sock);
int Ziti_connect(ziti_socket_t socket, ziti_handle_t ztx, const char *service, const char *terminator)
Connect socket to a Ziti service.
ziti_socket_t Ziti_socket(int type)
creates a socket handle(Windows) or file descriptor(*nix) suitable for connecting to a Ziti service
int ziti_socket_t
Definition zitilib.h:40
Binding to a service
function | usage |
Ziti_bind(srv, ztx, service, terminator) | binds given socket to the service/terminator within the context |
Ziti_listen(sock, backlog) | sets maximum number of pending inbound connections (similar to TCP backlog) |
Ziti_accept(srv, caller, caller_len) | accepts incoming connection and returns peer socket/handle |
int error =
Ziti_bind(srv, ztx,
"my-secure-service", NULL);
do {
char caller[128];
process_client(clt);
} while (!done);
close(srv);
ziti_socket_t Ziti_accept(ziti_socket_t socket, char *caller, int caller_len)
accept a client Ziti connection as a socket
int Ziti_listen(ziti_socket_t socket, int backlog)
marks the [socket] as a socket able to accept incoming connections
int Ziti_bind(ziti_socket_t socket, ziti_handle_t ztx, const char *service, const char *terminator)
Bind socket to a Ziti service.
Getting Help
Please use these community resources for getting help. We use GitHub issues for tracking bugs and feature requests and have limited bandwidth to address them.
Copyright© NetFoundry Inc.