Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Introduction

CoLT API v3 is a multitenancy web service. A tenant is an instance that is isolated from other instances and has its own data and configuration.

Endpoints are URLs providing access to the web services allowing certificate enrollment and issuance.

The API is designed to establish a communication channel via SSL Client Authentication, so when establishing the HTTPS channel, you must present a valid client certificate as part of the authentication mechanism.

Certificates are considered valid when they are issued by your organization CA (pilot or prod, depending on the environment), when they are within their validity period and when they are not revoked.

Additionally, the user and password must be presented. The values assigned have the following format (ask CertiSur for the values assigned to your company).

ORGANIZATION

Code Block
Email: adminXXXXX@lh2.ra
Pass: XXXXXXX

Operations and notation

Every operation is accessed via a specific URL. The endpoint contains a <tenant> value.

  • Each organization that uses this service will access its own proprietary console via its <tenant>. Please, ask CertiSur for the value assigned to your organization. Eg <tenant>="acme"

List of <operations>

  • sessions

  • individuals

  • requests

  • passcodes

  • revokes

  • certificates

Example: https://homo-panel.certisur.com:5443/acme/api/v3/individuals/

where “acme” is the name of the tenant.

The following sections describe in detail each operation, along with its input and output parameters.


Api Version: 3.0.3.2

Table of Contents
minLevel1
maxLevel2


Authentication

User authentication

POST

<tenant>/api/v3/auth/sign_in/

Input parameters

BODY

Code Block
{
    "email":"{{colt_be_admin_user}}",
    "password":"{{colt_be_admin_password}}"
}

Response

HEADER

Code Block
access-token
client
token_type
uid
expiry
Info

Each new request to the WS requires to include in the headers those parameters returned as HTTP response headers during the authentication with email and password.

Info

New HTTP response headers are returned with each order, and those headers should be used as an authentication mechanism in the next request.

You can find additional information on managing tokens in Appendix I – Authentication Token


Individuals

Obtain data from an individual. A parameter is passed to it and it returns all the individuals that match the indicated parameter. If no parameter is passed, it returns all the individuals.

POST

<tenant>/api/v3/individuals/search

Input parameters

It is possible to search by null and use wildcards (%) to retrieve a specific set of individuals. Ej

BODY

Code Block
individual: {
   first_name: "%ri%",
   company_attributes: { name: "Musim%"  }
}

All the possible fields:

Code Block
:individual = (
     :national_number, 
     :national_number_type, 
     :first_name, 
     :last_name, 
     :email, 
     :company_attributes: {
         :name,
         :national_number
      },
      :birthdate, 
      :address, 
      :country, 
      :phone,
      :country_phone_code
  )
  
  +:authentication_header

Response

BODY

Code Block
Individual Data

Return = headers(:access_token, :token_type, :client, :expiry, :uid)


List

Obtain a list of the 10 last loaded individuals.

GET

<tenant>/api/v3/individuals/

Input parameters

Code Block
Params = none

+:authentication_header

Response

BODY

Code Block
List of the last 10 loaded individuals

Return = headers(:access_token, :token_type, :client, :expiry, :uid)


Create

Create an individual.

POST

<tenant>/api/v3/individuals

Input parameters

Ej

BODY

Code Block
{
  :national_number, 
  :national_number_type, 
  :first_name, 
  :last_name, 
  :email, 
  :birthdate,
  :address, 
  :country, 
  :phone,
  :country_phone_code 
  :company_attributes:{:name,:national_number}, 
  :field_0
  …
  field_5
}

+:authentication_header

Required fields:

Code Block
:national_number, 
:national_number_type, 
:first_name, 
:last_name, 
:email

national_number_type values accepted: DNI, CI, etc. depending on tenant configuration.

Response

BODY

Code Block
Return = The individual is created and its associated data is returned.

Return = headers(:access_token, :token_type, :client, :expiry, :uid)

Note

If a user exists with the same "national_number_type" and "national_number" an error with code 5105.

Code Block
{
    "code": "5105",
    "description": "Ya existe un individuo con este número y tipo de identificador"
}


Enroll Request

Create

Create an Enrollment Request

POST

<tenant>/api/v3/requests/

Input parameters

BODY

Code Block
"individual": {
    "id", 
    "national_number_type", 
    "national_number"
  )

"request": {
    "field_1", 
    "field_2", 
    "channel_policy_id", 
    "approve"
  }

"policy": {
    "name"
  }
  
+:authentication_header

The individual parameter works in the same way as the individual search and must match just one record.

The content of field_1 to field_5 depends on is Tenant.

The content of the channel_policy_id field contains the identifier number of the Policy Keystore to assign to the request. If channel_policy_id is not sent, the Default Keystore Policy of the Policy whose “policy: { name }” is sent, is assigned to the request. If there is no Default Channel Policy associated to that Policy, the “default” keystore policy is assigned to the request.

approve equals to ‘true’ assign an approvement approvment from the Enrollment Administrator account to a new request.

If the policy_name is not sent, the request is created without the associated policy.

All the possible fields:

Code Block

Response

BODY

Code Block
The request is created for the individual and the data with which 
it was created is returned

Return = headers(:access_token, :token_type, :client, :expiry, :uid)

Show

It returns a request along with its data the same way as returned by CREATE.

GET

<tenant>/api/v3/requests/{{request_id}}


Update

Allows updating the common_name of a Request.

PUT

<tenant>/api/v3/requests/{{request_id}}

common_name is generated as “<first_name> <last_name>”. The first_name and last_name of the individual will not be modified.

Input parameters

BODY

Code Block
:request = (
    :first_name,
    :last_name
  )
  
+:authentication_header


Request + Mechanism

Create

POST

<tenant>/api/v3/requestsmechanism_request/

Input parameters

It works the same way as the creation of requests but with the addition of the following parameters:

BODY

Code Block
"request": {
    ...
    "mechanism":"onboarding" | "autoenroll",
    "mobile_number":"nnnnnnnnnnn",
    "country_mobile_code":"+nn",
    "app_name"": "SecureDoc"
    "approve": "true" | "false"
}

Response

Returns a mechanism_request record.

BODY

Code Block
{
    "id",
    "request": { ... },
    "app_name",
    "origin_request_id",
    "mechanism_request_id",
    "mechanism_status",
    "token",
    "mobile_number",
    "country_mobile_code",
    "enroll_url"
}

id

Internal Origin Request ID (don’t use)

origin_request_id

Random Hexa number, representing the Origin-Request-ID.

request

Request record

app_name

name of the application used to generate this request, eg: SecureDOC.

mechanism_request_id

value used by an external validation system to identify the validation process related to this request.

This value is used, by example, for the Biometric Validation System.

mobile_number

Mobile number used for whatsapp onboarding.

country_mobile_code

Country code for mobile number

enroll_url

If present, URL where the end-user must be redirected to complete the certificate enrollment.

enroll_url could be a default one defined either for the “onboarding” mechanism (/onboarding) or another one for the “autoenroll” mechanism (/pickup). It can also be defined (via Colt Admin Console) as one of the properties for the policy:

image-20240815-194331.png

For this field it is possible to define a template where the following variables will be replaced:

Code Block
[PANEL_BASE_URL]
[CURRENT_TENANT]
[ORIGIN_REQUEST_ID]
[TOKEN]

Response Example:

Code Block
{
    "id": 1,
    "request": {
        "company_name": "CertiSur S.A.",
        "state": "Ciudad Autonoma de Buenos Aires",
        "locality": "Ciudad Autonoma de Buenos Aires",
        "id": 1,
        "individual_id": 1,
        "common_name": "Armando",
        "national_number_type": "DNI",
        "national_number": "12342342",
        "country": "AR",
        "first_name": "Armando",
        "last_name": "33",
        "status": "enabled",
        "email": "jdoe@gmail.com",
        "request_type": "Initial",
        "approved": false,
        "policy": {
            "name": "acme",
            "friendly_name": "Acme Firma Digital",
            "validity": 365,
            "verification_model": "renaper"
        },
        "enabled_keystores": {
            "win_enh": {
                "security_policy": {
                    "capiSecPolicy": {
                        "id": null,
                        "mask": "1"
                    }
                }
            }
        },
        "pin_certificate": null,
        "adsec_op_type": "Initial",
        "act_as_initial": false
    },
    "app_name": "undef_app_name",
    "origin_request_id": "B2A768215FDFSDFD84D300FB8B2B9",
    "mechanism": "autoenroll",
    "mechanism_request_id": null,
    "mechanism_status": "pending",
    "token": "A88E9526F31C5DE81FDFFD8B74BE8FD256F5C",
    "mobile_number": "91161590622",
    "country_mobile_code": "+54",
    "first_name": "Armando",
    "last_name": "Carratala",
    "enroll_url": "http://localhost:5003/acme/pickup?origin_request_id=B2A768215FD84D300FB8B2B9&auth_token=A88E9526F31C5DE818B74BE8FD256F5C"
}

Show

It returns a request along with its data for origin_requests the same way as returned by CREATE.

GET

<tenant>/api/v3/requestsmechanism_request/{{origin_request_id}}

origin_request_id is the random hexa number, representing the Origin-Request-ID.


Update

Allows updating some values or fields of a Mechanism Request.

It sends the result of the onboarding process in order to approve or reject a request.

PUT

<tenant>/api/v3/mechanism_request/{{origin_request_id}}

origin_request_id is the random hexa number, representing the Origin-Request-ID.

Input parameters

BODY

Code Block
:origin_request = (
    :mechanism_request_id,
    :mechanism_status,
    :first_name,
    :last_name,
    :mobile_number,
    :country_mobile_code
  )
  
+:authentication_header

All the possible fields:

app_name

name of the application used to generate this request, eg: SecureDOC.

mechanism_request_id

value used by an external validation system to identify the validation process related to this request.

This value is used, by example, for the Biometric Validation System.

mechanism_status

could be ‘pending’, ‘started’, ‘completed’. When updating from ‘started’ to ‘completed’, the request gets the admin approval credits.

mobile_number

Mobile number used for whatsapp onboarding.

country_mobile_code

Country code for mobile number


Passcodes

Create

Create Passcodes associated with a Request (request) for an Individual. When making a new invocation, it will generate a new Passcode no matter if the previous one is still enabled or without use.

POST

<tenant>/api/v3/individuals/search

Input parameters

BODY

Code Block
:request=(:id)

+:authentication_header

Response

Code Block
The passcode tied to the request is created and the associated passcode data is returned.

Return = headers(:access_token, :token_type, :client, :expiry, :uid)

NOTE: If the request is executed two or more times on the same request (: id), it will generate a new pair of keys associated with each request

BODY

Code Block
{
  "passcode_status": "enabled",
  "pin_postal": "PHBXFE8H",
  "pin_email": "ZK99NUY4"
}

Revoke Request

Create

Create a revoke request

POST

<tenant>/api/v3/revokes

Input parameters

All the parameters are optional. The system will look for the certificates that match all the provided filters. It is recommended to send more than one parameter to limit the response to the specific individual and desired certificate.

If there is only one valid and non-expired certificate matched with the applied filters, a revocation request is created and returned.

BODY

Code Block
:certificate=(:serial),
:policy=(:name),
:revoke=(:revocation_reason, :approve),
:individual=(
    :id, 
    :national_number_type, 
    :national_number, 
    :first_name, 
    :last_name, 
    :email, 
    :birthdate, 
    :address, 
    :country, 
    :phone,
    :country_phone_code
)

+:authentication_header

Alternative values for revocation_reason:

  • ‘Replace’

  • 'Key compromise'

  • 'CA compromise'

  • 'Affiliation changed'

  • 'Superseded'

  • 'Cessation of operation'

  • 'Certificate hold'

  • 'Remove from CRL'

  • 'Privilege withdrawn'

  • 'AA compromise'

  • 'Unspecified'

Response

If success: a HTTP(200)

BODY

Code Block
{
  :id, 
  :revocation_reason, 
  :status, 
  :policy_name, 
  :individual_name, 
  :certificate {
    :serial,
    :data
  }
}

Example:

If error: a HTTP(400)

BODY

Code Block
{ 
  "code": "5106", 
  "description": "..." 
}

Possible description values:

  • No certificate has been found matching the filter provided

  • More than one certificate matches the filter provided

  • Not enough privileges to revoke a certificate belonging to the policy <policy_name>

  • There is already an open revoke

Example:


Search

POST

<tenant>/api/v3/revokes/search

Input parameters

BODY

Code Block
:from_date=(:fecha_desde),
:to_date=(:fecha_hasta),

All the possible fields:

Code Block
from_date and to_date fields format is: AAAA-MM-DD example: “2019-02-26”

The verification of the revocation status for a specific certificate must be done through the Certificates search.

Alternative values for revocation_reason:

  • 'Replace'

  • 'Key compromise'

  • 'CA compromise'

  • 'Affiliation changed'

  • 'Superseded'

  • 'Cessation of operation'

  • 'Certificate hold'

  • 'Remove from CRL'

  • 'Privilege withdrawn'

  • 'AA compromise'

  • 'Unspecified'

Response

BODY

Code Block
{
  :id, 
  :revocation_reason, 
  :status, 
  :policy_name, 
  :individual_name, 
  :certificate (:serial)
}

Example:

Code Block
{"revoke":{
      "id":1,
      "revocation_reason":"Unspecified",
      "status":"enabled",
      "policy_name":"bolsas_cereales_g2",
      "individual_name":"Juan Vinsmoke", 
      "serial":"3BCDBA3H7QWMM8B962607"
   }
}

Certificates

Search

Returns Individual certificate data

POST

<tenant>/api/v3/certificates/search

Input parameters

BODY

Code Block
:certificate= (
  :serial, 
  :id, 
  :from_date, 
  :to_date
),

:policy=(
  :name
),

:individual=(
  :id, 
  :national_number_type, 
  :national_number, 
  :first_name, 
  :last_name, 
  :email, 
  :birthdate, 
  :address, 
  :country, 
  :phone,
  :country_phone_code
)

Alternative values for status: ‘Revoked', ‘Expired', ‘Valid'

Response

BODY

Code Block
Certificate data

Example:

Code Block
{"certificates": [
    {
      "id": 20,
      "serial": "22190A2193BCE48A3D05B9CA67911094",
      "subject_dn": "/O=Bolsa de Comercio de Rosario/OU=ROSARIO G2/OU=  Empresa - 2017031705/OU=Documento – DNI16000000/CN=BCR Blanco/emailAddress=bcrblanco@bcr.com.ar",
      "issuer_dn": "/C=AR/O=Bolsa de Comercio de Rosario/OU=Symantec Trust Network/OU=FOR TEST PURPOSES ONLY/CN=TEST Autoridad Certificante Bolsa de Comercio de Rosario – G2",
      "not_before_date": "2017-09-17T00:00:00Z",
      "not_after_date": "2018-09-17T23:59:59Z",
      "individual_id": 4,
      "policy_id": 2,
      "created_at": "2017-09-17T20:33:23Z",
      "status": "valid"
    }
  ]
}


List

List the last 20 issued certificates.

GET

<tenant>/api/v3/certificates/

Input parameters

none

Response

BODY

Code Block
List of certificates

Enabled Keystores

(for features not associated to a request: verify, export, import)

List

Returns enabled keystores from a policy keystore with name “public” or “PUBLIC”

GET

<tenant>/api/v3/channel_policies

Input parameters

none

Response

BODY

Code Block
{
  :enabled_keystores= (
    :keystore_name_1= ( 
      :security_policy= ( ... ),
    ),
    ...
    :keystore_name_n= ( 
      :security_policy= ( ... ),
    )
  )
}

All the possible fields:

keystore_name_i

Possible values: atheidp, cloud, csk, etoken, ff_nss, macos, mobile, mtoken, pkcs12, safesign, win_enh, yubikey

Other values (compatibility): win_str, win_sc, vs_pta

security_policy

Depends on keystore_name value (see: Security Policy )

Example:

Code Block
{
    "enabled_keystores": {
        "etoken": {
            "security_policy": {
                "id": "etokensp",
                "installDummy": true,
                "generateOnBoard": true
            }
        },
        "mtoken": {
            "security_policy": {
                "id": "mtokensp",
                "installDummy": true,
                "generateOnBoard": true,
                "passMinLength": 12,
                "passComplexity": 1
            }
        },
        "csk": {
            "security_policy": {
                "id": "KSPolicyCSK",
                "passMinLength": 3,
                "passComplexity": 1,
                "passLockCount": 3,
                "passExpiration": 3,
                "lockTimeout": 2,
                "idleTimeout": 3,
                "certExport": 2
            }
        },
        "macos": {
            "security_policy": {}
        },
        "ff_nss": {
            "security_policy": {}
        },
        "pkcs12": {
            "security_policy": {}
        },
        "atheidp": {
            "security_policy": {
                "id": "atheidpsp",
                "installDummy": true,
                "generateOnBoard": true,
                "passMinLength": 12,
                "passComplexity": 1
            }
        },
        "safesign": {
            "security_policy": {
                "id": "safesignsp",
                "installDummy": true,
                "generateOnBoard": false,
                "passMinLength": 12,
                "passComplexity": 2
            }
        },
        "yubikey": {
            "security_policy": {
                "id": "yubikeysp",
                "installDummy": true,
                "generateOnBoard": true,
                "passMinLength": 12,
                "passComplexity": 1
            }
        }
    }
}


Alison Desktop Configs

List

Returns Alison Desktop configs to be used within the frontend environment

GET

<tenant>/api/v3/alison_configs

Input parameters

none

Response

BODY

Code Block
{
  :common= (
    :gui= (
      :theme,
      :logo
      :header
      :language( :key ),
      :warningDays   30
    ),
    :providers= (
      :desktop= (
        :urls= [ <list of urls> ] ],
        :accessToken
      )
    )
    :selector= (
      :thumbPrint,
      :profileName,
      :keyStoreId
     ),
     :filters= [ {} ],
     :min_version,
     :renew= ( :min_version ),
     :pickup= ( :min_version ),
     :verify"= ( :min_version ),
     :export= ( :min_version ),
     :import= ( :min_version ),
     :password= ( :min_version )
    ),
    :filters= (
        :renew= [ <filters cert select for this feature> ],
        :verify= [ <filters cert select for this feature> ],
        :mobile"= [ <filters cert select for this feature> ],
        :export"= [ <filters cert select for this feature> ]
    )
}

All the possible fields:

theme

Possible values: “theme1” or “theme2”

language key

Possible values: “es”, “en”

min_version

String containing the required minimum version of Alison Desktop to be used. If the required or a subsequent version is not installed a message will prompt the user to update. A min_version can be configured by feature and there is a generic min_version.

Example:

Code Block
{
    "common": {
        "gui": {
            "theme": "theme1",
            "logo": "/tenants/acme/images/clientLogo.jpg",
            "header": "",
            "language": {
                "key": "en"
            },
            "warningDays": 30
        },
        "providers": {
            "desktop": {
                "urls": [
                    "https://127.0.0.1:8004",
                    "https://localhost:8004"
                ],
                "accessToken": "ewogICJ2MiI6IHsKICAgICJ2ZXJzaW9uIjozLAogICAgImlkeCI6IjItTGljZW5zZSIsCiAgICAidmFsdWUiOiJleUpoYkdjaU9pSlNVekkxTmlKOS5leUpwWVhRaU9qRTFOemM1TnpnMk56a3NJbVY0Y0NJNk1UYzBOREkxTkRBd01Dd2lZMjl0Y0dGdWVVNWhiV1VpT2lKRFpYSjBhVk4xY2lCVExrRXVJaXdpWVd4c2IzZGxaRTl5YVdkcGJuTWlPbHNpS2k1alpYSjBhWE4xY2k1amIyMGlMQ0lxTG1ObGNuUnBjM1Z5TG01bGRDSXNJbUZzYVhOdmJtUmxjMnQwYjNBdWNHdHBhRzl6ZEM1amIyMGlMQ0poYkdsemIyNWtaWE5yZEc5d0xuQnJhV2h2YzNRdVkyOXRPamd3TURVaUxDSmphSEp2YldVdFpYaDBaVzV6YVc5dU9pOHZhM0JxYkdGblpHcHdZV2xwYlc1bFkyUmlaR051WkdwamFXcHZZV3hpYkdFaUxDSnNiMk5oYkdodmMzUTZPREF3TXlJc0ltMXZlaTFsZUhSbGJuTnBiMjQ2THk5a1ptSXdaV0kzTWkwMU56VTRMVFF6TjJJdFlUVXdPQzB5T0dSaE1UazRObVZrWm1RaUxDSnNiMk5oYkdodmMzUTZPREF3TkNJc0lteHZZMkZzYUc5emREbzRNREExSWl3aWJHOWpZV3hvYjNOMElpd2liRzlqWVd4b2IzTjBPakl3TURRaUxDSnNiMk5oYkdodmMzUTZNakF3TlNJc0lqRXlOeTR3TGpBdU1TSXNJakV5Tnk0d0xqQXVNVG80TURBMElpd2lNVEkzTGpBdU1DNHhPamd3TURVaVhYMC5heWFjaF9ybFRHN3lfN0NwZnRzT0xDQzNkXzRySjUzc0FlVE94RV8tTjdDOHpDN2VaT0ZQOEk1MFhSbTdVMktNM3hmMGhCLTF2bS1wZDV3WV84WGltSzNneFVaX3h5NG02ZWJ2bGZ2Zm52YUhmbENMdnhmSlF6WWRyVEV5cm1lc0F4QXJJVTJfQmtOcmREcDBRcktGaERxelVsLVJ3b3VMb2FYQTRFWGFtRGVwTXBoNWx0NEpzZlBDRDhfcmcwcHR3eUxEamtZdjViRm01clpoQkw4ZklLVmF3bnl5SFJjZUR6SllnNmdRdTU5OTVXczJkTGVhRWJ1UVBJZlU2YTlzb1ZHWjRYblZfWkZfTy1KeXA2SlVwVlNjVTNLSmNOQzVYOVJ0b2Y4akxWNF9nakJyaFJReHlQSDBCWk9QLWNkaEpRaVRrWnBhLXBvdGNlN01SdUpUTWciCiAgfQp9"
            }
        },
        "selector": {
            "thumbPrint": "",
            "profileName": "",
            "keyStoreId": ""
        },
        "filters": [
            {}
        ],
        "min_version": "3.4.0",
        "renew": {
            "min_version": "3.4.0"
        },
        "pickup": {
            "min_version": "3.4.0"
        },
        "verify": {
            "min_version": "3.4.0"
        },
        "export": {
            "min_version": "3.2.0"
        },
        "import": {
            "min_version": "3.4.0"
        },
        "password": {
            "min_version": "3.4.0"
        }
    },
    "filters": {
        "renew": [
            {
                "windowValidity": "-30,30",
                "issuer": "O=CertiSur"
            }
        ],
        "verify": [
            {
                "windowValidity": "0,*"
            }
        ],
        "mobile": [
            {
                "windowValidity": "0,*",
                "issuer": "O=CertiSur"
            }
        ],
        "export": []
    }
}


Authentication Description

The following information can be useful to understand the protocol used to authenticate each endpoint.

​Appendix I – Authentication Token

The Web Services authentication process is based on the token management documentation published in:

GitHub - lynndylanhurley/devise_token_auth: Token based authentication for Rails JSON APIs. Designed to work with jToker and ng-token-auth.

About token management

Tokens should be invalidated after each request to the API. The following diagram illustrates this concept:


During each request, a new token is generated. The access-token header that should be used in the next request is returned in the access-token header of the response to the previous request. The last request in the diagram fails because it tries to use a token that was invalidated by the previous request.

The only case where an expired token is allowed is during batch requests.

About batch requests

By default, the API updates the auth token for each request. But sometimes it's necessary to make several concurrent requests to the API, for example:

Batch request example

Code Block
$scope.getResourceData = function() {

  $http.get('/api/restricted_resource_1').success(function(resp) {
    // handle response
    $scope.resource1 = resp.data;
  });
  $http.get('/api/restricted_resource_2').success(function(resp) {
    // handle response
    $scope.resource2 = resp.data;
  });

};


In this case, it's impossible to update the access-token header for the second request with the access-token header of the first response because the second request will begin before the first one is complete. The server must allow these batches of concurrent requests to share the same auth token. This diagram illustrates how batch requests are identified by the server:


The "5 second" buffer in the diagram is the default used this API.

The following diagram details the relationship between the client, server, and access tokens used over time when dealing with batch requests:

Note that when the server identifies that a request is part of a batch request, the user's auth token is not updated. The auth token will be updated for the first request in the batch, and then that same token will be returned in the responses for each subsequent request in the batch (as shown in the diagram).