Skip to content

Authentication

Introduction

OpenCTI supports several authentication providers. If you configure multiple strategies, they will be tested in the order you declared them.

Activation

You need to configure/activate only the authentication strategy that you really want to propose to your users.

The product proposes two kinds of authentication strategies:

  • Form (asking user for a user/password),
  • Buttons (click with authentication on an external system).

Supported Strategies

Under the hood, we technically use the strategies provided by PassportJS. We integrate a subset of the strategies available with passport. If you need more, we can integrate other strategies.

Local users (form)

This strategy uses the OpenCTI database as a user management.

OpenCTI use this strategy as the default, but it's not the one we recommend for security reasons.

"local": {
    "strategy": "LocalStrategy",
    "config": {
        "disabled": false
    }
}

Production deployment

Please use the LDAP/Auth0/OpenID/SAML strategy for production deployment.

LDAP (form)

This strategy can be used to authenticate your user with your company LDAP and is based on Passport - LDAPAuth.

"ldap": {
    "strategy": "LdapStrategy",
    "config": {
        "url": "ldaps://mydc.domain.com:686",
        "bind_dn": "cn=Administrator,cn=Users,dc=mydomain,dc=com",
        "bind_credentials": "MY_STRONG_PASSWORD",
        "search_base": "cn=Users,dc=mydomain,dc=com",
        "search_filter": "(cn={{username}})",
        "mail_attribute": "mail",
        // "account_attribute": "givenName",
        // "firstname_attribute": "cn",
        // "lastname_attribute": "cn",
        "account_attribute": "givenName",
        "allow_self_signed": true
    }
}

If you would like to use LDAP groups to automatically associate LDAP groups and OpenCTI groups/organizations:

"ldap": {
    "config": {
        ...
        "group_search_base": "cn=Groups,dc=mydomain,dc=com",
        "group_search_filter": "(member={{dn}})",
        "groups_management": { // To map LDAP Groups to OpenCTI Groups
            "group_attribute": "cn",
            "groups_mapping": ["LDAP_Group_1:OpenCTI_Group_1", "LDAP_Group_2:OpenCTI_Group_2", ...]
        },
        "organizations_management": { // To map LDAP Groups to OpenCTI Organizations
            "organizations_path": ["cn"],
            "organizations_mapping": ["LDAP_Group_1:OpenCTI_Organization_1", "LDAP_Group_2:OpenCTI_Organization_2", ...]
        }
    }
}

SAML (button)

This strategy can be used to authenticate your user with your company SAML and is based on Passport - SAML.

"saml": {
    "identifier": "saml",
    "strategy": "SamlStrategy",
    "config": {
        "issuer": "mytestsaml",
        // "account_attribute": "nameID",
        // "firstname_attribute": "nameID",
        // "lastname_attribute": "nameID",
        "entry_point": "https://auth.mydomain.com/auth/realms/mydomain/protocol/saml",
        "saml_callback_url": "http://localhost:4000/auth/saml/callback",
        // "private_key": "MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwg...",
        "cert": "-----BEGIN CERTIFICATE-----\nMIICmzCCAYMCBgF2Qt3X1zANBgkqhkiG9w0BAQsFADARMQ8w...\n-----END CERTIFICATE-----",
        "logout_remote": false
        "want_assertions_signed": true,
        "want_authn_response_signed": true,
        // "mail_attribute": "email" -- optional, to be used when "nameID" is not an email.
    }
}

For the SAML strategy to work:

  • The cert parameter is mandatory (PEM format) because it is used to validate the SAML response. Depending on certificate format it may include the header, footer and newline (\n) characters.
  • The private_key (PEM format) is optional and is only required if you want to sign the SAML client request.

Certificates

Be careful to put the cert / private_key key in PEM format. Indeed, a lot of systems generally export the keys in X509 / PCKS12 formats and so you will need to convert them. Here is an example to extract PEM from PCKS12:

openssl pkcs12 -in keystore.p12 -out newfile.pem -nodes

Starting from OpenCTI 6.2 when want_assertions_signed and want_authn_response_signed SAML parameter are not present in OpenCTI configuration, the default is set to "true" by the underlaying library (passport-saml) when previously it was false by default. If you have issues after upgrade, you can try with both of them set to false.

Here is an example of SAML configuration using environment variables:

- PROVIDERS__SAML__STRATEGY=SamlStrategy 
- "PROVIDERS__SAML__CONFIG__LABEL=Login with SAML"
- PROVIDERS__SAML__CONFIG__ISSUER=mydomain
- PROVIDERS__SAML__CONFIG__ENTRY_POINT=https://auth.mydomain.com/auth/realms/mydomain/protocol/saml
- PROVIDERS__SAML__CONFIG__SAML_CALLBACK_URL=http://opencti.mydomain.com/auth/saml/callback
- PROVIDERS__SAML__CONFIG__AUDIENCE=http://opencti.mydomain.com/auth/saml/callback
- PROVIDERS__SAML__CONFIG__CERT=MIICmzCCAYMCBgF3Rt3X1zANBgkqhkiG9w0BAQsFADARMQ8w
- PROVIDERS__SAML__CONFIG__LOGOUT_REMOTE=false
- PROVIDERS__SAML__CONFIG__WANT_AUTHN_RESPONSE_SIGNED=true
- PROVIDERS__SAML__CONFIG__WANT_ASSERTIONS_SIGNED=true

OpenCTI supports mapping SAML Roles/Groups on OpenCTI Groups. Here is an example:

"saml": {
    "config": {
        ...,
        // Groups mapping
        "groups_management": { // To map SAML Groups to OpenCTI Groups
            "group_attributes": ["Group"],
            "groups_mapping": ["SAML_Group_1:OpenCTI_Group_1", "SAML_Group_2:OpenCTI_Group_2", ...]
        },
        "groups_management": { // To map SAML Roles to OpenCTI Groups
            "group_attributes": ["Role"],
            "groups_mapping": ["SAML_Role_1:OpenCTI_Group_1", "SAML_Role_2:OpenCTI_Group_2", ...]
        },
        // Organizations mapping
        "organizations_management": { // To map SAML Groups to OpenCTI Organizations
            "organizations_path": ["Group"],
            "organizations_mapping": ["SAML_Group_1:OpenCTI_Organization_1", "SAML_Group_2:OpenCTI_Organization_2", ...]
        },
        "organizations_management": { // To map SAML Roles to OpenCTI Organizations
            "organizations_path": ["Role"],
            "organizations_mapping": ["SAML_Role_1:OpenCTI_Organization_1", "SAML_Role_2:OpenCTI_Organization_2", ...]
        }
    }
}

Here is an example of SAML Groups mapping configuration using environment variables:

- "PROVIDERS__SAML__CONFIG__GROUPS_MANAGEMENT__GROUP_ATTRIBUTES=[\"Group\"]"
- "PROVIDERS__SAML__CONFIG__GROUPS_MANAGEMENT__GROUPS_MAPPING=[\"SAML_Group_1:OpenCTI_Group_1\", \"SAML_Group_2:OpenCTI_Group_2\", ...]"

OpenID Connect (button)

This strategy allows to use the OpenID Connect Protocol to handle the authentication and is based on Node OpenID Client which is more powerful than the passport one.

"oic": {
    "identifier": "oic",
    "strategy": "OpenIDConnectStrategy",
    "config": {
        "label": "Login with OpenID",
        "issuer": "https://auth.mydomain.com/auth/realms/mydomain",
        "client_id": "XXXXXXXXXXXXXXXXXX",
        "client_secret": "XXXXXXXXXXXXXXXXXX",
        "redirect_uris": ["https://opencti.mydomain.com/auth/oic/callback"],
        "logout_remote": false
    }
}

Here is an example of OpenID configuration using environment variables:

- PROVIDERS__OPENID__STRATEGY=OpenIDConnectStrategy 
- "PROVIDERS__OPENID__CONFIG__LABEL=Login with OpenID"
- PROVIDERS__OPENID__CONFIG__ISSUER=https://auth.mydomain.com/auth/realms/xxxx
- PROVIDERS__OPENID__CONFIG__CLIENT_ID=XXXXXXXXXXXXXXXXXX
- PROVIDERS__OPENID__CONFIG__CLIENT_SECRET=XXXXXXXXXXXXXXXXXX
- "PROVIDERS__OPENID__CONFIG__REDIRECT_URIS=[\"https://opencti.mydomain.com/auth/oic/callback\"]"
- PROVIDERS__OPENID__CONFIG__LOGOUT_REMOTE=false

OpenCTI support mapping OpenID Claims on OpenCTI Groups (everything is tied to a group in the platform). Here is an example:

"oic": {
    "config": {
        ...,
        // Groups mapping
        "groups_management": { // To map OpenID Claims to OpenCTI Groups
            "groups_scope": "groups",
            "groups_path": ["groups", "realm_access.groups", "resource_access.account.groups"],
            "groups_mapping": ["OpenID_Group_1:OpenCTI_Group_1", "OpenID_Group_2:OpenCTI_Group_2", ...]
        },
        // Organizations mapping  
        "organizations_management": { // To map OpenID Claims to OpenCTI Organizations
            "organizations_scope": "groups",
            "organizations_path": ["groups", "realm_access.groups", "resource_access.account.groups"],
            "organizations_mapping": ["OpenID_Group_1:OpenCTI_Group_1", "OpenID_Group_2:OpenCTI_Group_2", ...]
        },
    }
}

Here is an example of OpenID Groups mapping configuration using environment variables:

- PROVIDERS__OPENID__CONFIG__GROUPS_MANAGEMENT__GROUPS_SCOPE=groups
- "PROVIDERS__OPENID__CONFIG__GROUPS_MANAGEMENT__GROUPS_PATH=[\"groups\", \"realm_access.groups\", \"resource_access.account.groups\"]"
- "PROVIDERS__OPENID__CONFIG__GROUPS_MANAGEMENT__GROUPS_MAPPING=[\"OpenID_Group_1:OpenCTI_Group_1\", \"OpenID_Group_2:OpenCTI_Group_2\", ...]"

By default, the claims are mapped based on the content of the JWT access_token. If you want to map claims which are in other JWT (such as id_token), you can define the following environment variables:

- PROVIDERS__OPENID__CONFIG__GROUPS_MANAGEMENT__TOKEN_REFERENCE=id_token
- PROVIDERS__OPENID__CONFIG__ORGANIZATIONS_MANAGEMENT__TOKEN_REFERENCE=id_token

Alternatively, you can request OpenCTI to use claims from the userinfo endpoint instead of a JWT.

- PROVIDERS__OPENID__CONFIG__GROUPS_MANAGEMENT__READ_USERINFO=true
- PROVIDERS__OPENID__CONFIG__ORGANIZATIONS_MANAGEMENT__READ_USERINFO=true

Custom/Self-Signed CA Certificates

When using an OpenID Connect provider secured with a certificate issued by a custom Certificate Authority (CA) or a self-signed certificate, OpenCTI (running on Node.js) might not inherently trust this certificate. This can lead to connection errors like unable to get local issuer certificate.

To resolve this, you need to instruct OpenCTI to trust your custom CA certificate. This is achieved by providing the CA's root certificate to the Node.js environment via the NODE_EXTRA_CA_CERTS environment variable.

Steps to integrate your Custom CA Certificate:

  1. Obtain your CA's Root Certificate:

    • Export the public root certificate of the Certificate Authority that issued your OpenID provider's certificate. This file is typically in .pem, .crt, or .cer format. Ensure it contains the full certificate chain if applicable.
    • Place this certificate file (e.g., ca.crt) in a dedicated directory on your OpenCTI host machine, for example, /cert_volume/ca.crt.
  2. Mount the Certificate into the Docker Container:

    • Edit your docker-compose.yml file. Under the opencti service, add a volumes entry to mount your host certificate directory into the container.
    • Also, add an environment variable NODE_EXTRA_CA_CERTS pointing to the full path of your certificate inside the container.
    services:
      opencti:
        # ... other configurations
        volumes:
          - ./cert_volume:/cert_volume
        environment:
          - NODE_EXTRA_CA_CERTS=/cert_volume/ca.crt # Point to your CA cert inside the container
          # ... other environment variables
        # ...
    
    • Note: If you have multiple custom CA certificates, you can concatenate them into a single .pem file and point NODE_EXTRA_CA_CERTS to this combined file.
  3. Restart OpenCTI:

    • After modifying docker-compose.yml, restart your OpenCTI containers to apply the changes:
    docker-compose down
    docker-compose up -d
    

After these steps, OpenCTI should successfully establish a secure connection with your OpenID Connect provider using your custom certificate.

Security Warning: Do not disable certificate validation (e.g., by setting rejectUnauthorized to false if such an option existed for OIDC) in production environments. This is a significant security risk and makes your connection vulnerable to Man-in-the-Middle attacks. Always prefer trusting the CA certificate as described above.

Auth0 (button)

Auth0 is a specific implementation of OpenID Connect, if you need advanced configuration such as group management please use OpenID Connect. We may deprecate this strategy in a future version.

This strategy allows to use Auth0 Service to handle the authentication and is based on Node OpenID Client.

"authzero": {
    "identifier": "auth0",
    "strategy": "Auth0Strategy",
    "config": {
        "clientID": "XXXXXXXXXXXXXXXXXX",
        "baseURL": "https://opencti.mydomain.com",
        "clientSecret": "XXXXXXXXXXXXXXXXXX",
        "callback_url": "https://opencti.mydomain.com/auth/auth0/callback",
        "domain": "mycompany.eu.auth0.com",
        "audience": "XXXXXXXXXXXXXXX",
        "scope": "openid email profile XXXXXXXXXXXXXXX",
        "logout_remote": true,
        "logout_uri": "https://opencti.mydomain.com/oidc/logout",
    }
}

Here is an example of Auth0 configuration using environment variables:

- PROVIDERS__AUTHZERO__STRATEGY=Auth0Strategy
- PROVIDERS__AUTHZERO__CONFIG__CLIENT_ID=${AUTH0_CLIENT_ID}
- PROVIDERS__AUTHZERO__CONFIG__BASEURL=${AUTH0_BASE_URL}
- PROVIDERS__AUTHZERO__CONFIG__CLIENT_SECRET=${AUTH0_CLIENT_SECRET}
- PROVIDERS__AUTHZERO__CONFIG__CALLBACK_URL=${AUTH0_CALLBACK_URL}
- PROVIDERS__AUTHZERO__CONFIG__DOMAIN=${AUTH0_DOMAIN}
- "PROVIDERS__AUTHZERO__CONFIG__SCOPE=openid email profile"
- PROVIDERS__AUTHZERO__CONFIG__LOGOUT_REMOTE=true
#LOGOUT_URI can be set when logout_remote = true
- PROVIDERS__AUTHZERO__CONFIG__LOGOUT_URI="https://opencti.mydomain.com/oidc/logout"

Facebook (button)

This strategy can authenticate your users with Facebook and is based on Passport - Facebook.

"facebook": {
    "identifier": "facebook",
    "strategy": "FacebookStrategy",
    "config": {
        "client_id": "XXXXXXXXXXXXXXXXXX",
        "client_secret": "XXXXXXXXXXXXXXXXXX",
        "callback_url": "https://opencti.mydomain.com/auth/facebook/callback",
        "logout_remote": false
    }
}

Google (button)

This strategy can authenticate your users with Google and is based on Passport - Google.

"google": {
    "identifier": "google",
    "strategy": "GoogleStrategy",
    "config": {
        "client_id": "XXXXXXXXXXXXXXXXXX",
        "client_secret": "XXXXXXXXXXXXXXXXXX",
        "callback_url": "https://opencti.mydomain.com/auth/google/callback",
        "logout_remote": false
    }
}

GitHub (button)

This strategy can authenticate your users with GitHub and is based on Passport - GitHub.

"github": {
    "identifier": "github",
    "strategy": "GithubStrategy",
    "config": {
        "client_id": "XXXXXXXXXXXXXXXXXX",
        "client_secret": "XXXXXXXXXXXXXXXXXX",
        "callback_url": "https://opencti.mydomain.com/auth/github/callback",
        "logout_remote": false
  }
}

Client certificate (button)

This strategy can authenticate a user based on SSL client certificates. For this, you need to configure OpenCTI to start in HTTPS, for example:

"port": 443,
"https_cert": {
    "key": "/cert/server_key.pem",
    "crt": "/cert/server_cert.pem",
    "reject_unauthorized": true
}

And then add the ClientCertStrategy:

"cert": {
    "strategy":"ClientCertStrategy",
    "config": {
        "label":"CLIENT CERT"
    }
}

Afterwards, when accessing for the first time OpenCTI, the browser will ask for the certificate you want to use.

Proxy headers (automatic)

This strategy can authenticate the users directly from trusted headers.

{
  "header": {
    "strategy": "HeaderStrategy",
    "config": {
      "disabled": false,
      "header_email": "auth_email_address",
      "header_name": "auth_name",
      "header_firstname": "auth_firstname",
      "header_lastname": "auth_lastname",
      "logout_uri": "https://www.filigran.io",
      "groups_management": {
        "groups_header": "auth_groups",
        "groups_splitter": ",",
        "groups_mapping": ["admin:admin", "root:root"]
      },
      "organizations_management": {
        "organizations_header": "auth_institution",
        "organizations_splitter": ",",
        "organizations_mapping": ["test:test"]
      }
    }
  }
}

If this mode is activated and the headers are available, the user will be automatically logged without any action or notice. The logout uri will remove the session and redirect to the configured uri. If not specified, the redirect will be done to the request referer and so the header authentication will be done again.

Automatically create group on SSO

The variable auto_create_group can be added in the options of some strategies (LDAP, SAML and OpenID). If this variable is true, the groups of a user that logins will automatically be created if they don’t exist.

More precisely, if the user that tries to authenticate has groups that don’t exist in OpenCTI but exist in the SSO configuration, there are two cases:

  • if auto_create_group= true in the SSO configuration: the groups are created at the platform initialization and the user will be mapped on them.
  • else: an error is raised.

Example

We assume that Group1 exists in the platform, and newGroup doesn’t exist. The user that tries to log in has the group newGroup. If auto_create_group = true in the SSO configuration, the group named newGroup will be created at the platform initialization and the user will be mapped on it. If auto_create_group = false or is undefined, the user can’t log in and an error is raised.

"groups_management": {
  "group_attribute": "cn",
  "groups_mapping": ["SSO_GROUP_NAME1:group1", "SSO_GROUP_NAME_2:newGroup", ...]
},
"auto_create_group": true

Examples

LDAP then fallback to local

In this example the users have a login form and need to enter login and password. The authentication is done on LDAP first, then locally if user failed to authenticate and finally fail if none of them succeeded. Here is an example for the production.json file:

"providers": {
    "ldap": {
        "strategy": "LdapStrategy",
        "config": {
            "url": "ldaps://mydc.mydomain.com:636",
            "bind_dn": "cn=Administrator,cn=Users,dc=mydomain,dc=com",
            "bind_credentials": "MY_STRONG_PASSWORD",
            "search_base": "cn=Users,dc=mydomain,dc=com",
            "search_filter": "(cn={{username}})",
            "mail_attribute": "mail",
            "account_attribute": "givenName"
        }
    },
    "local": {
        "strategy": "LocalStrategy",
        "config": {
            "disabled": false
        }
    }
}

If you use a container deployment, here is an example using environment variables:

- PROVIDERS__LDAP__STRATEGY=LdapStrategy
- PROVIDERS__LDAP__CONFIG__URL=ldaps://mydc.mydomain.org:636
- PROVIDERS__LDAP__CONFIG__BIND_DN=cn=Administrator,cn=Users,dc=mydomain,dc=com
- PROVIDERS__LDAP__CONFIG__BIND_CREDENTIALS=XXXXXXXXXX
- PROVIDERS__LDAP__CONFIG__SEARCH_BASE=cn=Users,dc=mydomain,dc=com
- PROVIDERS__LDAP__CONFIG__SEARCH_FILTER=(cn={{username}})
- PROVIDERS__LDAP__CONFIG__MAIL_ATTRIBUTE=mail
- PROVIDERS__LDAP__CONFIG__ACCOUNT_ATTRIBUTE=givenName
- PROVIDERS__LDAP__CONFIG__ALLOW_SELF_SIGNED=true
- PROVIDERS__LOCAL__STRATEGY=LocalStrategy