1.2. Connecting to a Server¶
There are several ways to connect your client to a running xGT server:
The default port number is 4367. The xGT server listens on that port with a default hostname of “localhost”. Throughout this page, we assume the server platform has a DNS name of “my.example.com”.
1.2.1. Use SSH Tunneling¶
This strategy requires the user to have an SSH login account on the server platform running the xGT server process. To use this strategy, one must first establish an SSH connection, with tunneling, from their client laptop/desktop to the server platform:
$ ssh -L 4367:localhost:4367 my.example.com
The -L option says to map local port 4367 to the socket localhost:4367 on the server platform.
Now, all that a Python script needs to do is the same as if it were connecting to an xGT server running on its local platform:
import xgt
server = xgt.Connection(host = 'localhost')
1.2.2. Connect Via SSL-encrypted Network Connection¶
In order to run a secure xGT server, it is necessary to configure the server in this way as part of its startup settings (e.g. xgtd.conf file):
"system.usessl" : true,
"system.ssl_root_dir" : "/path/to/certs/root"
The /path/to/certs/root should point to the root directory where this directory subtree exists:
.
├── certs
│ ├── ca-chain.cert.pem # Certificate chain.
│ └── server.cert.pem # Server public certificate.
└── private
└── server.key.pem # Server private key.
Please consult your system administrator to determine if xGT has been set up for SSL connections.
To connect to an xGT server using SSL, the client needs to pass the following flags to xgt.Connection(): ssl, ssl_root_dir or ssl_server_cert, and ssl_server_cn.
The ssl flag needs to be set to True.
The ssl_root_dir flag can be set to the root directory containing the SSL certificates and private keys for the client.
The ssl_server_cert flag can be set to point to the certificate chain file.
The default location is ssl_root_dir + certs/ca-chain.cert.pem.
The ssl_server_cn flag should be set to the common name for the server listed on the server side SSL certificate.
The ssl_use_mtls flag can be set to True to require mutual TLS communication, in which the client’s identity is validated with its own certificates.
The default is False.
The ssl_client_cert flag can be set to point to the client’s certificate file when using mutual TLS.
The ssl_cient_key flag can be set to point to the client’s private key file when using mutual TLS.
These flags can be used instead of the ssl_root_dir flag when files are not in the same directory.
The xGT client expects the following directory structure for SSL certificates and private keys when using mutual TLS validation for the ssl_root_dir flag:
.
├── certs
│ ├── ca-chain.cert.pem # Certificate chain.
│ └── client.cert.pem # Client public certificate for MTLS.
└── private
└── client.key.pem # Client private key for MTLS.
The ssl_server_cert, ssl_client_cert and ssl_client_key can be used when those files do not reside in a common directory structure.
Here is a sample Python script showing connecting to a server via an SSL-encrypted channel for the simpler case:
import xgt
server = xgt.Connection(flags = {
'ssl' : True,
'ssl_server_cert' : "/path/to/client/certs/ca-chain.cert.pem",
'ssl_server_cn' : "my.xGT.cn" })
Note that the only requirement for the client is to have a file available describing the certificate chain.
The following is a sample Python script showing connecting to a server via an SSL-encrypted network using mutual TLS:
import xgt
server = xgt.Connection(flags = {
'ssl' : True,
'ssl_root_dir' : "/path/to/client/certs/",
'ssl_server_cn' : "my.xGT.cn",
'ssl_use_mtls' : True })
Mutual TLS requires that the client possess certificates validating its identity and stored in the expected directory structure. Consult your system administrator on how to obtain client certificates and how to store them securely on your client machine.
The following is an alternative example to connect to a server that requires mutual TLS. Each file is specified individually in this case.
import xgt
server = xgt.Connection(flags = {
'ssl' : True,
'ssl_server_cert' : "/path/to/client/certs/ca-chain.cert",
'ssl_server_cn' : "my.xGT.cn",
'ssl_client_cert' : "/path/to/client/certs/client.cert.pem",
'ssl_client_key' : "/path/to/client/certs/client.key.pem",
'ssl_use_mtls' : True })
A complete example on how to connect to a server using an SSL-encrypted channel is as follows:
import xgt
server = xgt.Connection(auth = xgt.BasicAuth(username = 'myuser',
password = getpass.getpass())
host = '192.168.1.1',
flags = { 'ssl' : True,
'ssl_server_cert' : "/path/to/client/certs/ca-chain.cert.pem",
'ssl_server_cn' : "my.xGT.cn" })
for ns in server.get_namespaces():
print (ns)
for frame in conn.get_frames():
print (frame)
As can be seen from the example script, once the connection has been established and authentication has been validated, the usage is the same. In this case, the script prints out the namespaces and frames that the user has access to on the server.
1.2.3. Connecting to an Open Port¶
Warning
This method is insecure without enabling SSL support. It is not recommended.
To use this connection strategy, the server must be configured with the DNS name of the server system as hostname. For example:
"system.hostname" : "my.example.com"
To connect to this server from anywhere on the internet, a Python script can do:
import xgt
server = xgt.Connection(host = 'my.example.com')
1.2.4. User Authentication¶
xGT supports using authentication to limit access to the server. The authentication type will be set up by the system administrator. xGT supports username/password, Kerberos single-sign-on, PKI certificate-based, and OIDC bearer token authentication; the sections below describe how to connect using each mechanism.
A user authenticates by passing an authentication class when constructing a Connection object using the keyword argument auth.
The xGT client supports the following authentication classes:
BasicAuth: Basic username / password authentication.KerberosAuth: Kerberos ticket-based single-sign-on authentication.PKIAuth: Public Key Infrastructure password-less authentication.ProxyPKIAuth: PKI authentication through a proxy, deriving the user identity from the actual client certificate.TrustedProxyAuth: PKI authentication through a trusted proxy, with the user ID supplied by the proxy.BearerTokenAuth: Direct bearer token authentication using a pre-obtained OIDC/JWT access token.OidcAuth: Interactive OIDC authentication via an external identity provider.OidcAuthorizationCodeAuth: Alias forOidcAuthwithflow='auth_code'fixed. Provided for users migrating from an earlier API; new code should useOidcAuthdirectly.OidcCredentialsAuth: Headless OIDC client-credentials authentication for automated use.
1.2.4.1. No Authentication¶
To create a connection using the Python client when the server is setup to not require authentication, the user doesn’t need to pass anything to the auth keyword argument as no authentication is the default:
conn = xgt.Connection()
1.2.4.2. User Password Authentication¶
To create a connection when the server is using username / password authentication, the user must pass a BasicAuth object to the auth keyword argument, providing a username and password:
conn = xgt.Connection(auth = xgt.BasicAuth("user01", "password01"))
When using a script or notebook, the Python getpass module can be used to securely authenticate a user’s password, prompting for a password input when run:
import getpass
conn = xgt.Connection(auth = xgt.BasicAuth("user01", getpass.getpass()))
If authenticating into xGT with the client’s currently logged in UNIX user or LDAP user, the module may also be used to retrieve the username:
import getpass
conn = xgt.Connection(auth = xgt.BasicAuth(getpass.getuser(), getpass.getpass()))
1.2.4.3. Kerberos Authentication¶
To connect to an xGT server using Kerberos-based single-sign-on capabilities, the user must have already authenticated to the third-party Kerberos Key Distribution Center (KDC) using a utility such as kinit.
To establish a connection, the user must use the KerberosAuth authentication class:
conn = xgt.Connection(host = "graph_server", auth = xgt.KerberosAuth())
Usually, no arguments need to be given to the KerberosAuth constructor as the user identity is derived from the already obtained Kerberos tickets.
However, the host argument must be supplied to the Connection constructor.
Depending on how the system running the xGT server has been set up, it might be necessary to specify another parameter called the Kerberos service principal.
The default value of the Kerberos service principal is computed from the name of the host running the service by the xGT client by using the prefix “xgtd/”.
The string “ROCKETGRAPH.COM”, in this example, is the name of the Kerberos realm, which usually maps to the network domain name.
The keyword argument principal on the KerberosAuth constructor allows the specification of that parameter when the default is not acceptable.
conn = xgt.Connection(host = "localhost",
auth = xgt.KerberosAuth("xgtd/graph_server@ROCKETGRAPH.COM"))
Consult your system administrator for details on how to connect to the xGT server using Kerberos.
1.2.4.4. PKI Authentication¶
PKI authentication can be enabled for xGT when configured to use SSL-encrypted connections and mutual TLS (Transport Layer Security).
Mutual TLS requires the use of client keys and x509 certificates.
If those certificates include a valid userId field, then that is enough to provide that identity to xGT for connection and access.
conn = xgt.Connection(auth = xgt.PKIAuth(ssl_root_dir = '/home/user/ssl_certs'))
The connection to xGT will use PKI authentication if the class PKIAuth is used for the auth parameter.
A directory containing a valid client key and certificate is used by the Python client to initialize an encrypted, mutual TLS connection.
The directory must have the structure described in Using an SSL Secure Channel.
The default for those files is ~/.ssl, that is the .ssl directory under the user’s home directory.
Consult your system administrator for details on how to connect to the xGT server using PKI.
1.2.4.5. OIDC Authentication¶
Experimental: This feature is experimental and may change in future releases.
xGT supports authentication through an external OpenID Connect (OIDC) identity provider (IdP). The xGT Python client obtains an access token from the IdP and presents it to the server, which validates it and maps the token claims to a user identity and group memberships.
For interactive use (scripts, notebooks, or any context where a user is
present), use OidcAuth.
When the server is configured with OIDC settings, no additional arguments are
required; the client fetches the issuer and client ID from the server
automatically:
conn = xgt.Connection(host = "graph_server", auth = xgt.OidcAuth())
After successful authentication, the access token is cached under
~/.rocketgraph/oidc/ and reused on subsequent calls without prompting again,
as long as the token remains valid.
To point at a specific IdP, supply issuer and client_id explicitly:
conn = xgt.Connection(
host = "graph_server",
auth = xgt.OidcAuth(issuer = "https://idp.example.com/realms/xgt",
client_id = "xgtd-client"))
OidcAuth supports two login flows, selected via the flow
argument.
Authorization code flow (flow='auth_code') opens a browser window on
the local machine and listens on a loopback port for the IdP’s redirect.
This is the most seamless experience when running a script on a desktop or
laptop where a browser is available.
The user logs in normally in the browser and the script continues automatically
once the redirect arrives.
Device flow (flow='device') does not require a browser on the machine
running the script.
Instead, xGT prints a short URL and a user code.
The user opens the URL on any device (phone, another browser tab, etc.),
enters the code if prompted, and logs in.
The script polls in the background and continues once the login is confirmed.
Use this flow when running on a remote server, inside a container, or in any
environment where opening a local browser is not practical.
The default flow='auto' selects authorization code flow when the IdP
advertises an authorization endpoint, and device flow otherwise.
In SSH sessions the device flow is preferred automatically even when both are
available, since there is typically no local browser to redirect to.
An SSH session is detected by the presence of the SSH_CONNECTION or
SSH_TTY environment variables.
If neither is set (for example inside a container or when connecting through a
non-standard proxy), automatic SSH detection will not trigger and
flow='device' should be specified explicitly.
To force a specific flow:
# Always use device flow (good for SSH or remote servers).
conn = xgt.Connection(host = "graph_server",
auth = xgt.OidcAuth(flow = 'device'))
# Always use authorization code flow.
conn = xgt.Connection(host = "graph_server",
auth = xgt.OidcAuth(flow = 'auth_code'))
To suppress the automatic browser launch in authorization code flow while still using it (the URL is printed instead):
conn = xgt.Connection(host = "graph_server",
auth = xgt.OidcAuth(flow = 'auth_code', open_browser = False))
For CI/CD pipelines, cron jobs, or any automated context where no user is
present, use OidcCredentialsAuth.
The IdP issues a token directly in exchange for a client_id and
client_secret with no browser or user interaction required:
import os
conn = xgt.Connection(
host = "graph_server",
auth = xgt.OidcCredentialsAuth(
issuer = "https://idp.example.com/realms/xgt",
client_id = "my-service-client",
client_secret = os.environ["MY_SERVICE_SECRET"]))
The client_secret should be supplied via an environment variable or secrets
manager rather than hardcoded.
If a bearer token has already been obtained by other means it can be passed
directly with BearerTokenAuth:
conn = xgt.Connection(host = "graph_server", auth = xgt.BearerTokenAuth(token))
Consult your system administrator for details on how the server is configured for OIDC. For server-side setup see OIDC Authentication.