Secure and monitor IPC connections¶
This page shows you how to secure a q server with authentication and authorization hooks, and how to monitor and interrupt IPC connections in production.
Properly securing and monitoring IPC connections is essential for production systems.
Authentication and authorization¶
q provides hooks for implementing custom security logic.
Authentication¶
You can enable basic user/password authentication by starting the q process with a user credentials file (using the -u or -U flag). When a client connects, the server validates the provided credentials against this file.
For more advanced authentication (for example, LDAP or Kerberos), you can override the .z.pw callback. This function receives the username and password and must return a boolean indicating whether the connection is allowed.
Authorization¶
After a user authenticates, you can implement finer-grained permissions by customizing the .z.pg (sync) and .z.ps (async) callbacks. This allows you to restrict access to certain functions or data based on the user (.z.u) or their connection handle (.z.w).
Example: Allowlist of allowed functions for sync calls
// On the server:
q)\p 5000
// Define a list of functions that clients are allowed to call
q)allowedFns:(`func1;`func2;`func3;+;-)
// Define a validation function that signals an error if the call is disallowed
q)checkFn:{if[not x in allowedFns;'(.Q.s1 x)," not allowed"]}
// Recursively validate the parse tree
// If x is a general list (0h), check if the first element is a function call
// Then recursively validate any nested lists
q)validatePT:{if[0h=type x;if[(not 0h=type first x)&1=count first x;checkFn first x];.z.s each x where 0h=type each x]}
// Override .z.pg to check the request before executing it
// If the request is a string (10h), parse it first
q).z.pg:{if[10h=type x;x:parse x];validatePT x;eval x}
A client that attempts to call a disallowed function receives an error:
// On the client:
q)h: hopen `::5000
// This call is allowed
q)h"1+1"
2
// This call is blocked by our custom .z.pg
q)h"1*1"
'* not allowed
[0] h"1*1"
^
Performance considerations
For high-volume data feeds, such as tickerplants that use .z.ps for data publication, consider bypassing these authorization checks for trusted handles to avoid performance overhead.
Monitor and handle errors¶
Track connections¶
You can inspect active connections on a server:
.z.Hreturns a list of all active socket handles-38!xprovides a detailed dictionary of information about all open sockets
For custom connection tracking, use the .z.po (open) and .z.pc (close) callbacks to maintain a state table of connected clients.
Interrupt requests¶
You can interrupt a long-running synchronous query on the client by sending an interrupt signal (for example, using kill -s INT <PID>) to the client process. The client then receives a 'rcv handle error, and the handle is no longer valid.
// Client sends a long-running query that blocks
q)h"system\"sleep 30\""
// --- User interrupts the client process from another terminal ---
// Client console shows the error:
'rcv handle: 4. OS reports: Interrupted system call
[0] h"system\"sleep 30\""
^
// The handle is now broken and cannot be used
q)h"1+1"
'Cannot write to handle 4. OS reports: Bad file descriptor
[0] h"1+1"
^