Advanced Keystroke Action Policy

Policies for Advanced Keystroke Action are different from normal Privilege Management for Unix and Linux policies because they have a different function to fulfill. The policy is defined as a JSON object split into a number of separate sections including variables, prerun, complete actions, macros, readonly, and policy. The primary section of the policy is an ordered list of match and action nodes. These match the command line, or other variable, and perform specified actions if the match is successful.


The preamble defines the name of the configuration and whether debug can be enabled.

Through the command line:
set akadebug 10
   "name": "demo",
   "cfg": {
      "debug_enabled": true,


The variables section allows the configuration of variables that can be used within the policy. These variables, by default are read/write within the policy but may be defined as readonly in the readonly section. All JSON data types are supported, including booleans (true/false), strings, integers, floating point numbers (reals), and arrays of datatypes using the JSON format. These can then be referred to by name using a notation similar to bash. For example, ${varname}" or "${arrayelement[2]}. Some of the variables are special in that they can only hold specific values. For example, editor can only be emacs or vi, and keymap can only hold specific definitions of keys (similar to the NetBSD libedit or GNU readline names.

The variable input is the current command line, and if it is rewritten it will change the command line. If it is set to null, it removes the current input and returns the user to the command line.

"variables": {
   "editor": "emacs",  "prompt": "$ ",  "ro_var": "this variable is readonly",  "remote_prompt":
   "keymap": [{ "key": "^I",  "value": "ed-complete" }

Key definitions by default are listed below.

In vi input mode, input characters are bound to the following editor commands by default:

Ctrl-D, EOF vi-list-or-eof
Ctrl-H, BS vi-delete-prev-char
Ctrl-J, LF ed-newline
Ctrl-M, CR


Ctrl-Q ed-tty-start-output








Ctrl-[, ESC vi-command-mode
Ctrl-\, QUIT ed-tty-sigquit
Ctrl-?, DEL


All other input characters except the NUL character (Ctrl-@) are bound to ed-insert.

In vi command mode, input characters are bound to the following editor commands by default:

Ctrl-A ed-move-to-beg
Ctrl-C, INT ed-tty-sigint
Ctrl-E ed-move-to-end
Ctrl-H, BS


Ctrl-J, LF ed-newline
Ctrl-K ed-kill-line
Ctrl-L, FF


Ctrl-M, CR


Ctrl-N ed-next-history




Ctrl-Q ed-tty-start-output
Ctrl-R ed-redisplay
Ctrl-S ed-tty-stop-output
Ctrl-U vi-kill-line-prev
Ctrl-W ed-delete-prev-word
Ctrl-[, ESC em-meta-next
Ctrl-\, QUIT ed-tty-sigquit
Space ed-next-char
# vi-comment-out
$ ed-move-to-end
% vi-match
+ ed-next-history
, vi-repeat-prev-char
- ed-prev-history
. vi-redo
/ vi-search-prev
0 vi-zero
1 to 9 ed-argument-digit
: ed-command
; vi-repeat-next-char
? vi-search-next
@ vi-alias
A vi-add-at-eol
B vi-prev-big-word
C vi-change-to-eol
D ed-kill-line
E vi-end-big-word
F vi-prev-char
G vi-to-history-line
I vi-insert-at-bol
J ed-search-next-history
K ed-search-prev-history
N vi-repeat-search-prev
O ed-sequence-lead-in
P vi-paste-prev
R vi-replace-mode
S vi-substitute-line
T vi-to-prev-char
U vi-undo-line
W vi-next-big-word
X ed-delete-prev-char
Y vi-yank-end
[ ed-sequence-lead-in
^ ed-move-to-beg
_ vi-history-word
a vi-add
b vi-prev-word
c vi-change-meta
d vi-delete-meta
e vi-end-word
f vi-next-char
h ed-prev-char
i vi-insert
j ed-next-history
k ed-prev-history
l ed-next-char
n vi-repeat-search-next
p vi-paste-next
r vi-replace-char
s vi-substitute-char
t vi-to-next-char
u vi-undo
v vi-histedit
w vi-next-word
x ed-delete-next-char
y vi-yank
| vi-to-column
~ vi-change-case
Ctrl-?, DEL ed-delete-prev-char
Meta-O ed-sequence-lead-in
Meta-[ ed-sequence-lead-in

In emacs mode, input characters are bound to the following editor commands by default:

0 to 9 ed-digit
Ctrl-@, NUL em-set-mark
Ctrl-A ed-move-to-beg


Ctrl-C, INT ed-tty-sigint
Ctrl-D, EOF em-delete-or-list




Ctrl-H, BS em-delete-prev-char
Ctrl-J, LF ed-newline
Ctrl-K ed-kill-line
Ctrl-L, FF ed-clear-screen
Ctrl-M, CR ed-newline
Ctrl-N ed-next-history
Ctrl-O ed-tty-flush-output
Ctrl-P ed-prev-history
Ctrl-Q ed-tty-start-output
Ctrl-R ed-redisplay
Ctrl-S ed-tty-stop-output
Ctrl-T ed-transpose-chars
Ctrl-U ed-kill-line
Ctrl-V ed-quoted-insert
Ctrl-W em-kill-region
Ctrl-X ed-sequence-lead-in
Ctrl-Y em-yank
Ctrl-Z, TSTP ed-tty-sigtstp
Ctrl-[, ESC em-meta-next
Ctrl-\, QUIT ed-tty-sigquit
Ctrl-] ed-tty-dsusp
Ctrl-?, DEL em-delete-prev-char
Ctrl-Meta-H ed-delete-prev-word
Ctrl-Meta-L ed-clear-screen
Ctrl-Meta-_ em-copy-prev-word
Meta-0 to 9 ed-argument-digit
Meta-B ed-prev-word
Meta-C em-capitol-case
Meta-D em-delete-next-word
Meta-F em-next-word
Meta-L em-lower-case
Meta-N ed-search-next-history
Meta-O ed-sequence-lead-in
Meta-P ed-search-prev-history
Meta-U em-upper-case
Meta-W em-copy-region
Meta-X ed-command
Meta-[ ed-sequence-lead-in
Meta-b ed-prev-word
Meta-c em-capitol-case
Meta-d em-delete-next-word
Meta-f em-next-word
Meta-l em-lower-case
Meta-n ed-search-next-history
Meta-p ed-search-prev-history
Meta-u em-upper-case
Meta-w em-copy-region
Meta-x ed-command
Ctrl-Meta-? ed-delete-prev-word


The prompt variable is the prompt that the user will see to type at. The remote_prompt is important in that AKA attempts to wait for the remote prompt before letting the user type at the command line. This should make interaction clearer and more intuitive without mixing input and output characters in the input/output terminal data stream.

Other special variables are:

  • runuser: The remote run user
  • runhost: The fully qualified domain name of the the remote run host
  • runhostname: The simple hostname of the remote run host
  • runcmd: The command line passed to pbssh
  • argv: The command line array passwd to pbssh
  • prompt_wait: The maximum time to wait for remote command to run (in milliseconds)
  • history: The number of command line history entries to save for the next session
  • input: The submitted command line
  • prerun_prompt_wait: The maximum time to wait for remote command to run when executing the pre-run as the user session starts (in milliseconds)
  • prerun_slowdown: The delay time added to each prerun command to slow down the prerun (in milliseconds)
  • remote_prompt: The remote prompt, used by Advanced Keystroke Action profiles to synchronize the terminal session input and output sequences
  • akadebug: Built-in debugging to allow the policy writer to diagnose issues in policy
  • pkcert: The value of the pk_cert passed into the Advanced Keystroke Action service
  • pkserver: The value of the pk_server passed into the Advanced Keystroke Action service
  • pkdomain: The value of the pk_domanit passed into the Advanced Keystroke Action service

For more information, please see the NetBSD editline(7) man page.


The prerun section is an array of string commands that are submitted to the remote system before any user commands can be submitted. It is recommended, if possible, to define prompts, etc, so they can be waited for using remote_prompt variable. The strings are submitted one after another with a short delay, but with not intelligent processing. If processing is required is recommended that normal policy is used.

"prerun": [   "PS1=##prompt##:",   "unset PROMPT_COMMAND"  ],


The filter section is an array of strings that are filtered from the session output and are therefore not displayed on the client terminal session.

"filter": [   "Filtered string one",   "Filtered string two"  ],


The login sequence object details what happens with a successful or unsuccessful login. It details whether the user is allowed any input during the login phase, the successful/unsuccessful messages and strings that are matched to determine whether it was successful:

"login_sequence" : {
   "input_allowed" : true,
   "successful" : "*** Login sequence successful ***",
   "denied" : "*** Failed login sequence – access denied ***",
   "prematch" : [
       {"Last login: " : true },
       {"Access denied" : false }


Completion is a list of strings that can be used to complete command lines (usually when the ed-complete key is submitted). If more than one string can complete the command, the list will be provided. If only one matches, the current command line is rewritten to the completion string. There are two types of completion value. A line completion, where the who line will be compared up to the cursor, and word completion that simply checks the previous word.

"complete": [  {""value": "compabcd",   "type" : "line" },{"value" : "compadef", "type" : "line"},{"value": "compxyz","type" : "word" } ],


Macros are an ordered list of regular expression patterns and rewrite strings. It is used to simply rewrite the current command line if patterns match when return is pressed. This should simplify the majority of policy that are simple rewrites.


"macros": [
   { "pattern": "macroa(b)(c)d", "value": "echo macro rewrites to ${1} ${2}" }

When the user types macroabcd, it rewrites the command line to echo macro rewrites to b c, and it executes the command on the remote system.


The readonly section is a simple list of variables that are readonly and cannot be rewritten. This is useful for constant strings or messages.

"readonly": {
   "ro_var": true


The policy section is an ordered list of matching conditions and actions that are taken if the match is positive. Matching is processed against variables or user input, and can be any normal operation, including regular expressions. Actions can be:

  • Accept: Immediately accept the current command line and submit the command line to the remote host to execute.
  • Reject: Immediately reject the current command line, optionally displaying a message.
  • Restart: Restart processing the policy list from the beginning.
  • Readonly: Mark the specified variable readonly for the rest of the session.
  • Disable: Execute the current command line, but disable command line processing until either the specified string is matched in the output, or the remote prompt is once again displayed. This allows interactive sessions to be authorized.
  • Unset: Unset the specified variable.
  • Printf: Display the specified message to the users terminal session, processing specified arguments to make up the message.
  • Sendf: Send the specified message to the remote application as if typed, processing specified arguments to make up the input.
  • Set: Set the specified variable to a constant or calculated value. Constant values can include any data type, or can reference another variable. Calculated values can be integer or floating point math, shift or logic values, substrings, substituted strings, upper/lower case strings, split or sprint strings. Arguments can be constants or specified variable values, or the arguments matched from the regular expression match.
    • Operators on integers include add(+), subtract (-), divide (/), multiply (*), logical AND (&&), bitwise AND (&), logical OR (||), bitwise OR (|), NOT (!), shift left (<<), shift right (>>), modulo divide (%).
    • Operators on floating point include add(+), subtract (-), divide (/), multiply (*).
    • Operators on strings include concatenation (+), substitute (sub), substring (substr), uppercase (upper), lowercase (lower), split/tokensize string (split) and sprintf to format a string with arguments.
    • Operators on arrays include append/extend (+), remove (-) and index set (=).

The match node consists of a singular expression match, or an array of called and or or which are evaluated to a logical AND or OR of the constituent singular expression matches.

Simple match:
"match": { "op": "=",  "${var}": "var1", "value": 123 }
Logical AND of simple matches:
"match": { "and" = [
   {"op": "=",  "var": "${var1}", "value": 123 },
   { "op": "=",  "var": "${var2}", "value": 678}
Logical OR of simple matches:
"match": { "or" = [
   {"op": "=",  "var": "${var1}", "value": 123 },
   { "op": "=",  "var": "${var2}", "value": 678}

A Simple Example of Policy

This shows a simple policy where the command line is matched against the user typing PS1=….. If it matches, the command is rejected with a suitable message to the user.
"policy": [
   "match": {
   "op": "=~",
   "var": "${input}",
   "value": "PS1=.*"
   "actions": [
       "action": "reject",
       "value": "sorry, you cannot reset the prompt"
}, ….

For more examples, please see the demo policy in the default Advanced Keystroke Action database.