Realm

In order to create a new realm you must create a new directory below config.d/realm with the internal name of the realm. While it is possible to just create a symlink or copy from the realm.tpl directory we recommend to read the instructions in the Quickstart document as this approach gives you the best options for later upgrades of the configuration.

When finished add a new section in the file system/realms.yaml where the new section key is identical to the new realm directory name used for the realm directory. Change the new realm section entries to match the desired values for the new realm.

Please note that you might need to perform additional steps based on the overall configuration options such as creating templates, static content or mapping items. Those should be outlined in the configurations setup document.

The realm configuration consists of five major parts:

Authentication
Configure which authentication mechanisms to use for the realm. If you use internal authentication methods, this also holds your user databases.
Crypto layer
Define name and path of your keyfiles and settings for the crypto tokens used.
Profiles
Anything related to your certificate and crl profiles
Publishing
How and where to publish certificates and crls
Workflow
Configuration data of the internal workflow engine.

Authentication

Authentication is done via authentication handlers, multiple handlers are combined to an authentication stack.

Stack

The realm’s authentication combines the configured authentication handlers to offer different authentication stacks. On the login page, the entries of the stack are shown and a user can choose between them. The stacks are configured in the file located in <realm-basedir>/auth/stack.yaml. If, for example, one would like to enable only anonymous logins and password based logins, this file’s contents could be as follows:

Anonymous:
    label: Guest Login
    handler: Anonymous
    type: anon

User:
    label: User Login
    type: passwd
    handler:
      - Operator Password
      - User Password

In this configuration, the realm offers two login stacks, namely Anonymous and User. The stack Anonymous uses the Handler Anonymous and the logins using the stack User may be performed by both handlers Operator Password and User Password. Therefore, when selecting this variant, both logins with credentials configured for Operator Password and for User Password are supported. You can define any number of stacks and reuse the same handlers inside. You must define at least one stack.

Advanced Usage

Use the TLS Client Certificate from the HTTPS connection:

Certificate:
    handler: Certificate
    type: x509

Use the REMOTE_USER field from basic auth, optionally pass additonal ENV keys from advanced auth modules:

BasicAuth:
    handler: NoAuth
    type: client
    envkeys:
        email: AUTH_PROVIDER_email_field

Handler

A handler consists of a perl module, that provides the authentication mechanism. The name of the handler is used to be referenced in the stack definition, mandatory entries of all handlers is type. All handlers are defined below OpenXPKI::Server::Authentication, where type is equal to the name of the module.

Here is a list of some handlers and their configuration sets, more can be found in the sample configuration. Extensive documentation can be found in the perldoc for the classes.

Anonymous user

If you just need an anonymous connection, you can use the Anonymous handler.

Anonymous:
    type: Anonymous
    # the verbose name is shown in the UI
    name: Guest User

System:
    type: Anonymous
    role: System

If no role is provided, you get the anonymous role. Do never set any other role than system, unless you exactly know what you are doing!

x509 based authentication

X509 uses the SSL client authentication feature of apache/mod_ssl. It passes the signer certificate to a validation function that cryptographically checks the chain and tests the chain against a list of trusted anchors.

The configuration is the same for both handlers (apart from the class name):

Certificate:
    type: ClientX509
    role: User
    trust_anchor:
        realm: userca

Please check perldoc OpenXPKI::Server::Authentication::X509 for details.

Password database handler

The password database handler allows to specify user/password/role pairs directly inside the configuration.

Password:
    type: Password
    description: I18N_OPENXPKI_CONFIG_AUTH_HANDLER_DESCRIPTION_PASSWORD
    user:
        John Doe:
            digest: "{SSHA}TZXM/aqflDDQAmSWVxSDVWnH+NhxNU5w"
            role: User
        root:
            digest: "{SSHA}+u48F1BajP3ycfY/azvTBqprsStuUnhM"
            role: CA Operator
        raop:
            digest: "{SSHA}ejZpY22dFwjVI48z14y2jYuToPRjOXRP"
            role: RA Operator

The passwords are hashed, the used hash algorithm is given as prefix inside the curly brackets. You should use only SSHA which is “salted sha1”. For compatibility we support plain sha (sha1), md5, smd5 (salted md5) and crypt. You can created the salted passwords using the openxpkiadm CLI tool (openxpkiadm hashpwd). Alternatively, for batch processing, a salted sha1 password could be generated using openssl:

salt="$(openssl rand -base64 3)"
password="secretpassword"
echo -n $(echo -n "$password$salt" | openssl sha1 -binary)$salt | openssl enc -base64

Note: As of v3.10 we also directly support the format of the openssl passwd command starting with the Dollar sign.

If you plan to use static passwords for a larger amount of users, you should consider to use a connector instead:

Password:
    type: Password
    user@: connector:auth.connector.userdb

Define the user database file inside auth.connector.yaml:

userdb:
    class: Connector::Proxy::YAML
    LOCATION: /home/pkiadm/democa-userdb.yaml

The user file has the same structure as the user section above, the user names are the on the top level:

root:
    digest: "{SSHA}+u48F1BajP3ycfY/azvTBqprsStuUnhM"
    role: CA Operator
raop:
    digest: "{SSHA}ejZpY22dFwjVI48z14y2jYuToPRjOXRP"
    role: RA Operator

You can share a user database file within realms.

Authentication connectors

There is a family of authentication connectors. The main difference against other connector is, that the password is passed as a parameter and is not part of the path. Check for connectors starting with Connector::Builtin::Authentication. The connector only validates the password, therefore the role must be set in the configuration (same for all users handled by this item):

Password Connector:
    type: Connector
    role: User
    source@: connector:auth.connector.localuser

An example config to authenticate RA Operators against ActiveDirectory using their company mail address and windows password including check of a group membership (this is just the authentication, set the role in the handler config):

raop-ad:
    class: Connector::Builtin::Authentication::LDAP
    LOCATION: ldap://ad.company.com
    base: dc=company,dc=loc
    binddn: cn=binduser
    password: secret
    filter: "(&(mail=[% LOGIN %])(memberOf=CN=RA Operator,OU=SecurityGroups,DC=company,DC=loc))"

External authentication

If you have a proxy or sso system in front of your OpenXPKI server that authenticates your users, the external handler can be used to set the user information:

ExternalAuth:
    type: NoAuth
    role: User

Crypto layer

group assignment

You must provide a list of token group names at crypto.type to tell the system which token group it should use for a certain task. The keys are the same as used in system.crypto.tokenapi (see Crypto layer (global)). See TODO for a detailed view how the token assignment works.

type:
  certsign: ca-certsign
  datasafe: vault
  scep: scep

token setup

Any token used within OpenXPKI needs a corresponding entry in the realm’s token configuration at crypto.token. The name of the token is the alias name you used while registering the correspondig certificate.

token:
  democa-certsign:
    backend: OpenXPKI::Crypto::Backend::OpenSSL

    key: /etc/openxpki/local/keys/democa/ca-certsign-1.pem

    # possible values are OpenSSL, nCipher, LunaCA
    engine:         OpenSSL
    engine_section: ''
    engine_usage:   ''
    key_store:      OPENXPKI

    # OpenSSL binary location
    shell: /usr/bin/openssl

    # OpenSSL binary call gets wrapped with this command
    wrapper: ''

    # random file to use for OpenSSL
    randfile: /var/openxpki/rand

    # Secret group
    secret: default

The most important setting here is key which must be the absolute filesystem path to the keyfile. The key must be in PEM format and is protected by a password. The password is taken from the secret group mentioned by secret. See TODO for the meaning of the other options.

using inheritance

Usually the tokens in a system share a lot of properties. To simplify the configuration, it is possible to use inheritance in the configuration:

token:
    default:
        backend: OpenXPKI::Crypto::Backend::OpenSSL
        ......
        secret: default

    server-ca-1:
        inherit: default
        key: /etc/openxpki/local/keys/democa/ca-certsign-1.pem
        secret: gen1pass

    server-ca-2:
        inherit: default
        key: /etc/openxpki/local/keys/democa/ca-certsign-2.pem

Inheritance can daisy chain profiles. Note that inheritance works top-down and each step replaces all values that have not been defined earlier but are defined on the current level. Therefore you should not use undef values but the empty string to declare an empty setting.

You can use template toolkit to autoconfigure the key property, this way you can roll over your key without modifying your configuration.

The example above will then look like:

token:
    default:
        backend: OpenXPKI::Crypto::Backend::OpenSSL
        key: /etc/openxpki/local/keys/democa/[% ALIAS %].pem
        ......
        secret: default

    server-ca-1:
        inherit: default
        secret: gen1key

    server-ca-2:
        inherit: default

If you need to name your keys according to a custom scheme, you also have GROUP (ca-signer) and GENERATION (1) available for substitution. The certificate identifier is also available via IDENTIFIER.

token in datapool

Instead of having the tokens key files on the filesystem it is possible to store them in the datapool. Please be aware of the security implications of putting your CAs PRIVATE KEYS into the datapool which is readable by anybody with access to the database or the openxpki socket!

You must set the attribute key_store to DATAPOOL and provide the name of the used datapool key using the key attribute:

scep:
    inherit: default
    key_store: DATAPOOL
    key: "[% ALIAS %]"

This will read the SCEP key from the datapool, the used namespace is sys.crypto.keys. You must import the key yourself, e.g. from the CLI:

openxpkicli set_data_pool_entry --arg namespace=sys.crypto.keys \
    --arg key=scep-1 \
    --arg encrypt=1 \
    --filearg value=file_with_key.pem

Using the datapool encryption hides the value of the key from database admins but still exposes it in clear text to anybody with access to the command line tool! It should be obvious that you can not store the data-vault token this way as it is needed to decrypt the datapool items!

Starting with v3.8 the openxpkiadm alias command can handle key imports internally, you can load the certificate and key in one step:

openxpkiadm alias --realm democa --token scep \
    --file democa-scep.crt --key democa-scep.pem

HSM via PKCS#11

Tokens may be maintained by HSMs as well. For HSMs a standardized interface called PKCS#11 is defined. OpenSSL supports this interface as well through its pkcs11 engine. This OpenSSL engine is supplied by the OpenSC and has to be configured in OpenXPKI.

To use PKCS#11 token in OpenXPKI the following settings has to be made:

  • The engine has to be set to PKCS11. This causes OpenXPKI to use OpenSSL’s PKCS#11 engine.
  • The key has to correspond to the key’s identification of the HSM. For example when the YubiHSM2 is used, the string slot_0-label_issuer_key would correspond to a stored key with the label issuer_key.
  • As engine_section one can define how OpenSSL accesses the HSM. OpenXPKI always generates OpenSSL configurations on the fly when needed and if this token is accessed, the contents of OpenSSL’s [engine_section] are pasted in this configuration file. To define which passphrase is used to unlock the HSM, the configuration parameter PIN should be set as shown in the example. OpenXPKI ensures to replace any occurrence of the string __PIN__ with the corresponding secret.
  • The value of engine_usage defines when the engine should be used. Often ALWAYS is the preferred setting.

To use PKCS#11 tokens in OpenXPKI, the backend of the token has to be set to PKCS11.:

token:
  signer:
    backend: OpenXPKI::Crypto::Backend::OpenSSL
    key: "slot_0-label_issuer_key"
    engine: PKCS11
    engine_section: |
      engine_id              = pkcs11
      dynamic_path           = /usr/lib/engines/engine_pkcs11.so
      MODULE_PATH            = /usr/lib/x86_64-linux-gnu/pkcs11/yubihsm_pkcs11.so
      PIN                    = __PIN__
      init                   = 0
    engine_usage: 'ALWAYS'
    key_store: ENGINE
    shell: /usr/bin/openssl
    randfile: /var/openxpki/rand
    wrapper: ''
    secret: signer

The linked secret is only used to get access to the HSM. The secret used to unlock the HSM can be configured normally. For the YubiHSM2 for example a secret group that uses the authentication key 0x0001 with the password password would be the following:

secret:
  signer:
    label: YubiHSM password
    method: literal
    value: 0001password
    cache: daemon

Note: To be able to use the YubiHSM2 with OpenSSL, two environment variables has to be set (YUBIHSM_PKCS11_CONF and YUBIHSM_PKCS11_MODULE). If those environment variables are set when the server is started, the OpenXPKI process inherits these values.

Secret Groups

A secret group maintains the password cache for your keys and PINs. You need to setup at least one secret group for each realm. The most common version is the plain password:

secret:
  default:
    label: One Piece Password
    method: plain
    cache: daemon

This tells the OpenXPKI daemon to ask for the default only once and then store it “forever”. If you want to have the secret cleared at the end of the session, set cache: session.

To increase the security of your key material, you can configure secret splitting by dividing the PIN entry into n components that are simply concatenated.

secret:
  ngkey:
    label: Split secret Password
    method: plain
    total_shares: 3
    cache: daemon

If you have a good reason to put your password into the configuration, use the literal type:

secret:
  insecure:
    label: A useless Password
    method: literal
    value: my_not_so_secret_password
    cache: daemon

You can also use the secret groups for other purposes, in this case you need to add “export: 1” to the group. This allows you to use the get_secret method of the TokenManager (OpenXPKI::Crypto::TokenManager) to retrieve the plain value of the secret.

Profiles

certificates

There is a TODO:link seperate section about certificate profile configuration.

certificate revocation list

A basic setup must provide at least a minimum profile for crl generation at crl.default:

digest: sha1
validity:
    nextupdate: +000014
    renewal: +000003

The nextupdate value gives the validity of the created crl (14 days). The renewal value tells OpenXPKI how long before the expiry date of the current crl the system is allowed to create a new one. If you set this to a value larger than nextupdate, a new crl is created every time you trigger a new crl creation workflow. Note: If a certificate becomes revoked, the renewal interval is not checked.

crl at “end of life”

Once your ca certificate exceeds its validity, you are no longer able to create new crls (at least if you are using the shell modell). OpenXPKI allows you to define a different validity for the last crl, which is taken if the next calculated renewal time will exceed the validity of the ca certificate:

validity:
    nextupdate: +000014
    renewal: +000003
    lastcrl: 20301231235900

crl extensions

The following code shows the full set of supported extensions, you can skip what you do not need:

extensions:
    authority_info_access:
        critical: 0
        ca_issuers: http://myca.mycompany.com/[% CAALIAS.ALIAS %]/cacert.pem
        ocsp:
        - http://ocsp1.mycompany.com/
        - http://ocsp2.mycompany.com/

    authority_key_identifier:
        critical: 0
        keyid:  1
        issuer: 1


    issuer_alt_name:
        critical: 0
        # If the issuer has no subject alternative name, copying returns
        # an empty extension, which is problematic with both RSA SecurId
        # tokens and Cisco devices!
        copy: 0

There are two specialities in handling the ca_issuers and ocsp entries in the authority_info_access section:

  1. You can pass either a list or a single scalar to each item.
  2. For each item, template expansion based on the signing ca certificate is available. See TODO:link for details.

The CAALIAS hash also offers the components of the alias in GENERATION and GROUP.

Publishing

Publishing of certificates and crl is done via connectors (TODO:link). The default workflows look for targets at publishing.entity and publishing.crl. Each target can contain a list of key-value pairs where the value points to a valid connector item while the keys are used for internal logging:

entity:
    int-repo@: connector:publishing.connectors.ldap
    ext-repo@: connector:publishing.connectors.ldap-ext

crl:
    crl@: connector:publishing.connectors.cdp

certificate publishing

The OpenXPKI packages ship with a sample configuration for LDAP publication but you might include any other connector. The publication workflow appends the common name of the certificate to the connector path and passes a hash containing the subject (subject) and the DER (der) and PEM (pem) encoded certificate.

The configuration block looks like this:

connectors:
    ldap-ext:
        class: Connector::Proxy::Net::LDAP::Single
        LOCATION: ldap://localhost:389
        base: ou=people,dc=mycompany,dc=com
        filter: (|(mail=[% ARG %]) (objectCategory=person))
        binddn: cn=admin,dc=mycompany,dc=com
        password: secret
        attrmap:
            der: usercertificate;binary

        create:
            basedn: ou=people,dc=mycompany,dc=com
            rdnkey: cn

        schema:
            cn:
                objectclass: inetOrgPerson
                values:
                    sn: copy:self
                    ou: IT Department

Let’s explain the parts.

class: Connector::Proxy::Net::LDAP::Single
LOCATION: ldap://localhost:389
base: ou=people,dc=mycompany,dc=com
filter: (|(mail=[% ARG %]) (objectCategory=person))
binddn: cn=admin,dc=mycompany,dc=com
password: secret

Use the Connector::Proxy::Net::LDAP::Single package and use cn=admin,dc=mycompany,dc=com and secret to connect with the ldap server at ldap://localhost:389 using ou=people,dc=mycompany,dc=com as the basedn. Look for an entry of class person where the mailadress is equal to the common name of the certificate.

attrmap:
    der: usercertificate;binary

Publish the content of the internal key der to the ldap attribute usercertificate;binary.

create:
    basedn: ou=people,dc=mycompany,dc=com
    rdnkey: cn

This enables the auto-creation of non-existing nodes. The dn of the new node is create from the basedn and the new component of class “cn” set to the path-item which was passed to the connector (in our example the mailadress). You also need to pass the structural information for the node to create.

schema:
    cn:
        objectclass: inetOrgPerson
        values:
            sn: copy:self
            ou: IT Department

crl publishing

The crl publication workflow appends the common name of the ca certificate to the connector path and passes a hash containing the subject (subject), the components of the parsed subject as hash (subject_hash) and the DER (der) and PEM (pem) encoded crl.

The default configuration comes with a text-file publisher for the crl:

cdp:
    class: Connector::Builtin::File::Path
    LOCATION: /var/www/openxpki/myrealm/crls/
    file: "[% ARGS %].crl"
    content: "[% pem %]"

If the dn of your current ca certificate is like “cn=My CA1,ou=ca,o=My Company,c=us”, this connector writes the PEM encoded crl to the file /var/www/openxpki/myrealm/crls/My CA1.crl

Notification

Notifications are triggered from within a workflow. The workflow just calls the notification layer with the name of the message which should be send, which can result in no message or multiple messages on different communication channels.

The configuration is done per realm at notification. Supported connectors are Mail via SMTP (plain and html) and RT Request Tracker (using the RT::Client::REST module from CPAN). You can use an arbitrary number of backends, where each one has its own configuration at notification.mybackend.

Most parts of the messages are customized using the Template Toolkit. The list of available variables is given at the end of this section.

Sending mails using SMTP

You first need to configure the SMTP backend parameters:

backend:
    class: OpenXPKI::Server::Notification::SMTP
    host: localhost
    port: 25
    starttls: 0
    username: smtpuser
    password: smtpsecret
    debug: 0
    use_html: 0

Class is the only mandatory parameter, the default is localhost:25 without authentication. Debug enables the Debug option from Net::SMTP writing to the stderr.log which can help you to test/debug mail delivery. To use html formatted mails, you need to install MIME::Lite and set use_html: 1. The handler will fall back to plain text if MIME::Lite can not be loaded.

The mail templates are read from disk from, you need to set a base directory:

template:
    dir:   /home/pkiadm/democa/email/

Below is the complete message configuration as shipped with the default issuance workflow:

default:
    from: no-reply@mycompany.com
    reply: helpdesk@mycompany.com
    to: "[% cert_info.requestor_email %]"
    cc: helpdesk@mycompany.com

message:
    csr_created:   # The message Id as referenced in the activity
        user:   # The internal handle for this thread
            template: csr_created_user
            subject: CSR for [% cert_subject %]
            prefix: PKI-Ticket [% meta_wf_id %]
            images:
                banner: head.png
                footer: foot.png

        raop:      # Another internal handle for a second thread
            template: csr_created_raop  # Suffix .txt is always added!
            to: reg-office@mycompany.com
            cc: ''
            reply: "[% cert_info.requestor_email %]"
            subject: CSR for [% cert_subject %]

    csr_rejected:
        user:
            template: csr_rejected
            subject: CSR rejected for [% cert_subject %]

    cert_issued:
        user:
            template: cert_issued
            subject: certificate issued for [% cert_subject %]

The default section is not necessary but useful to keep your config short and readable. These options are merged with the local ones, so any local variable is possible and you can overwrite any default at the local configuration (to clear a setting use an empty string, the images hash is NOT merged recursively).

the idea of threads

You might have recognized that there are two blocks below messages.csr_created. Those are so called threads, which combine messages sent at different times to share some common settings. With the first message of a thread the values given for to, cc and prefix are persisted so you can ensure that all messages that belong to a certain thread go to the same receipients using the same subject prefix. Note, that settings to those options in later messages are ignored!

receipient information

The primary receipient and a from address are mandatory:

  • to: The primary receipient, single value, parsed using TT
  • from: single value, NOT parsed

Additional receipients and a seperate Reply-To header are optional:

  • cc: comma seperated list, parsed using TT
  • reply: single value, NOT parsed

All values need to be rfc822 compliant full addresses.

composing the subject

The subject is parsed using TT. If you have specified a prefix, it is automatically prepended.

composing the message body

The body of a message is read from the filename specified by template, where the suffix ‘.txt’ is always apppended. So the full path for the message at messages.csr_created.user is /home/pkiadm/democa/email/csr_created_user.txt.

html messages

If you use the html backend, the template for the html part is read from csr_created_user.html. It is allowed to provide either a text or a html template, if both files are found you will get a multipart message with both message parts set. Make sure that the content is the same to avoid funny issues ;)

It is possible to use inline images by listing the image files with the images key as key/value list. The key is the internal identifier, to be used in the html template, the value is the name of the image file on disk.

With a config of:

user:
    template: csr_created_user
    ....
    images:
        banner: head.png
        footer: foot.png

You need to reference the image in the html template like this:

<body>
    <img src="cid:banner" title="My Company Logo Banner" />
    .....
    <img src="cid:footer" title="My Company Logo Footer" />
</body>

The images are pulled from the folder images below the template directory, e.g. /home/pkiadm/democa/email/images/head.png. The files must end on gif/png/jpg as the suffix is used to detect the correct image type.

To test your notification config, you can trigger a test message via the command line interface:

openxpkicli send_notification --arg message=testmail --param notify_to=me@company.org

RT Request Tracker

The RT handler can open, modify and close tickets in a remote RT system using the REST interface. You need to install RT::Client::REST from CPAN and setup the connection:

backend:
    class: OpenXPKI::Server::Notification::RT
    server: http://rt.mycompany.com/
    username: pkiuser
    password: secret
    timeout: 30

The timeout value is optional with a default of 30 seconds.

As the SMTP backend, it uses templates on disk to build the ticket contents, so we also need to set the template directory:

template:
    dir:   /home/pkiadm/democa/rt/

You can share the templates for SMTP and RT handler and reuse most parts of your configuration, but note that the syntax is slightly different from SMTP. Here is the complete message configuration as shipped with the default issuance workflow:

message:
    csr_created:  # The message Id as referenced in the activity
        main:     # The internal handle for this ticket
            - action: open
              queue: PKI
              owner: pki-team
              subject: New CSR for [% cert_subject %]
              to: "[% cert_info.requestor_email %]"
              template: csr_created
              priority: 1

            - action: comment
              template: csr_created_comment
              status: open

    csr_approved:
        main:
            - action: update
              status: working

    csr_rejected:
        main:
            - action: correspond
              template: csr_rejected
              priority: 10

    cert_issued:
        main:
            - action: comment
              template: cert_issued_internals

            - action: correspond
              template: cert_issued
              status: resolved

The RT handler also makes use of threads, where each thread is equal to one ticket in the RT system. The example uses only one thread = one ticket. Each message can have multiple threads and each thread consists of at least one action.

Create a new ticket

You should make sure that a ticket is created before you work with it! The minimum information required to open a ticket is:

action: open
queue: PKI
owner: pki-team
subject: New CSR for [% cert_subject %]
to: "[% cert_info.requestor_email %]"

The to field must be an email address, which is used to fill the requestor field in RT.

Additional fields are:

  • cc: comma sep. list of email addresses to be assigned to the ticket, parsed with TT
  • template: filename for a TT template, used as inital text for the ticket (.txt suffix is added)
  • priority: priority level, usually a numeric value
  • status: ticket status, usually one of “new”, “open”, “resolved”, “stalled”, “rejected”, and “deleted”.

comment or correspond to a ticket

The maximum configuration is:

action:   comment  # or "correspond"
status:   open     # optional
priority: 5        # optional
template: csr_created_comment  # .txt is added

For comment the result of the parsed template is added to the ticket history.

For correspond the result is also mailed to the ticket receipients (this is a feature of RT, we dont send any mails).

Note: If the template parser returns an empty string, no operation is done on the ticket.

update status/priority without text

The update action allows you to set status/priority without creating a text entry in the history:

action: update
status: stalled
priority: 0

You can call update with either status or priority or both.

setting custom fields

You can set custom field values using the update action. Any key/value pair in the block (except the ones above) is considered to be a custom field. The values are parsed using TT:

action: update
priority: 3
custom-field1: My custom value
custom-field2: My other custom value

Note: This feature is untested!

closing a ticket

You can close a ticket with the above commands by setting the status-flag. For convenience there is a shortcut, setting the status to “resolved”:

action: close

Template Variables

The notification handler injects those values into the template parser on any invocation.

realm info

  • meta_pki_realm (key of the current realm)
  • meta_label (verbose realm name as defined at system.realms.$realm.label)
  • meta_baseurl (baseurl as defined at system.realms.$realm.baseurl)

request related context values (scalars)

  • csr_serial
  • cert_subject
  • cert_identifier
  • cert_profile

request related context values (hashes)

  • cert_subject_parts
  • cert_subject_alt_name
  • cert_info
  • approvals

misc

  • creator
  • requestor (real name of the requestor, if available assembled from cert_info.requestor_gname + requestor_name, otherwise the word “unknown”)

Certificate Info Plugin

The default install also provides a plugin to get detailed informations on a certificate:

[% USE Certificate %]

Serial: [% Certificate.serial(cert_identifier) %]
Hex Serial: [% Certificate.serial_hex(cert_identifier) %]
CSR: [% Certificate.csr_serial(cert_identifier) %]
Issuer: [% Certificate.issuer(cert_identifier) %]
Status: [% Certificate.status(cert_identifier) %]

Body-Subject: [% Certificate.body(cert_identifier, 'Subject') %]

The body method will return any field of the body structure offered by the get_cert api method. Fore further info check the modules documentation (OpenXPKI::Template::Plugin::Certificate).

Workflow

The definition of the workflows is still in the older xml format, already used in older OpenXPKI releases but its management is included into the connector now. The XML files are located in the folder named _workflow (note the underscore!) in the top level direcotry of the realm. If you are upgrading from an older installation, you can just move your old workflow*.xml files here and add an outer “openxpki” tag to the workflow.xml file.