BankID Authorization API

Version: 1.2 modified on 18.11.2021

The goal of this document is to describe the authorization feature of the BankID. It provides guidance on how to understand and use the authorization API.

How to read the guideline

The CAPITALIZED words throughout these guidelines have a special meaning as defined in RFC2119:

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document, are to be interpreted as described in RFC2119.

Glossary

  • Request object - Object representing action which requires end-users consent.
  • Authorization - If not explicitly stated otherwise, in context of this document Authorization is defined as voluntary and conscious consent with action represented by object
  • IDP - Identity Provider - A component on the side of the Bank which handles authorization (in OpenID Connect sense) and consent and issues tokens
  • Authorization server - A component on the side of the Bank with handles request objects, and their authorization by end user
  • OIDC - OpenID Connect - An authentication framework, it is a superset of the OAuth2 authorization framework
  • RP - Relying Party - An OpenID Connect a middleman and orchestrator which sits between Service Providers and Banks
  • SeP - Service Provider - A third party which is registered in the BankID system and intends to consume Bank APIs
  • JWT - JSON Web Token - A Base64 encoded, signed and possibly encrypted JSON document
  • JWK - JSON Web Key - A JSON describing keys for JWT encryption, description, signing and verification

Authorization use-case

  • You wish to request explicit consent from the End-User for some action, for example to obtain consent or sign document with end-user.

Authorization overview

BankID has a universal system for request object authorization based on OpenID Financial-grade API. Prior to start of authorization on end user side client SHOULD obtain end-user access token with grated scope "authorization". Authorization API is secured by using mutual TLS and use of signed and encrypted JWTs on endpoints. See more in Security Considerations.

Aplication setting

To enable BankID SIGN, you need to perform several steps in the application administration:

  • turn on the SIGN product in the "Products" tab
  • save the production environment of the application for the changes to take effect
  • check that two-factor authentication is enabled in the application settings, if not, enable it

Authorization usage

Authorization flow is composed of 3 endpoints - /ros , /authorize and /token. For additional validation of signed document SeP can use endpoint /verification.)

  • Endpoint /ros MUST be called first for registration of request object on authorization server. Request object must be passed directly in request body. Endpoint returns request_uri that is used in other endpoints. In case of document signature resource return upload url for document upload. Document MUST be uploaded prior to call of /authorize endpoint.

      Notes on interface: 
      - Authorization Bearer is not required for this resource. If it is not present, BankID will redirect end user to standard authentication process and after that will perform authorization or document signature.
      - If end user is not authenticated use of id_token_hint field is highly recommended, since IdP SHOULD allow skipping initial identification.
      - if end user is not authenticated additional scopes openid and authorization MUST be present
      - If you require to sign document, LoA 3 MUST be sent as acr_value, otherwise BankID will return error 
      - remote_authorization constitutes different behavior see remarks in general notes
      - If field scope is present and not empty, IdP will request consent for new scopes added by SeP prior or after authorization, if end user doesn't consent or authorize BankID returns error to SeP.
    
  • Endpoint /authorize is called next for initiating authorization on object by end-user. Returns redirect for end-user to authorize the object on Authorization Server. After a client's consent Authorization server redirects end-user on redirect URL provided in request. In case of anonymous ROS, authentication flow is initiated on BankID side to authenticate end-user. Interface is straightforward.

  • Standard OIDC endpoint /token is used to get final result of authorization on Authorization server. Returns encrypted and signed JWT with the authorized object in an id_token and subject who had made authorization. A signed document can be downloaded on url found in the structured scope field in ID token.

  • Endpoint /verification may be used to get authenticity of signature in a document made by BankID. Document_id from PDF metadata must be used as parameter.

Notes on general structures

Structured scope

Structured scope is object that represents action or statement for which end user gives consent by using identity proofing with substantial assurance level if required. BankID currently provides 2 types of object:

  • SignObject
  • DocumentObject

SignObject SHOULD be used for simple text consents, confirming of advertisements or similar tasks. Since SignObject is very generic structure, SeP should send correct ui_locale of end user and fill labels and values in correct language. IdPs SHOULD support minimum of Czech and English mutations. Other langugages MAY NOT be supported and these languages SHOULD be converted to Czech or English following rules that Czech and Slovak ui_locales SHOULD be converted as Czech, other languages as English.

DocumentObject CAN be used for signing legally binding PDF with digital signatures with provable audit trails.

Document signature

You can request document signature by end user via BankID. Authorization flow differs in this case, since BankID actively process document and provides additional features.

On call of /ros resource only metadata of document are sent and BankID returns upload_url additionally. Document MUST be uploaded prior to call of /authorize resource.

If you fail to upload document prior to call, /authorize will send error response and request object will be deleted.

On call of /authorize resource BankID validates the document, makes hash and flow continues as normal.

On a redirect from end-users browser, you get authorization code and BankID adds digital signature by user's certificate to document and seals it with a qualified seal.

Call of /token resource with authorization code returns response with an id_token, which contains URL of signed document, which is stored in BankID.

Document signing procedure

0. Prerequisites for the successful signing of the document

  • I have an application based on the developer portal. The application has been set to jwks_uri in BankID developer portal with public keys for signing and encrypting communication (use with sig and enc value). The JWKs_uri application endpoint is publicly available.
  • In the case of a production approach, the correct Sign product is selected. This is not necessary for the Sandbox.
  • If I want to sign a PDF document, I need to ensure that the PDF is:
    • Unlocked (signature respectively revision can be added in the document)
    • Contains custom metadata documetId, which includes the document identifier. This identifier is a string that would be unique within the SeP approach. BankID only validates the existence of this id, not its uniqueness.
    • If I require a visual signature element, I know which page I want to place the element on, and there is space on the given page (see below for dimensions and location).

1. Initiate authorization by sending document metadata and OIDC authentication parameters

To start the authorization flow, it is necessary to send the metadata of the signed document via the POST /ros endpoint.

Request payload of /ros endpoint is required in JWE format. Thus, the JSON payload request is first signed with the sig key of the application in the form of JWS and then encrypted with enc BankID key (from JWKs issued on the BankID environment). You can find the correct URL of BankID JWKs keys for the given environment (Sandbox or Production) in the developer portal at setting up your application on the credentials tab after "unpacking" the OIDC Discovery area.

Example request for /ros:

curl --location --request POST 'https://oidc.sandbox.bankid.cz/ros' \
--header 'Content-Type: application/jwe' \
--data-raw 'eyJraWQiOiJycC1lbmNyeXB0IiwiY3R5IjoiSldUIiwiZW5jIjoiQTI1NkdDTSIsImFsZyI6IlJTQS1PQUVQLTI1NiJ9.d6_-yDTqjHoJxyQZSle2V.......J9UNAzTEVlLCjTQMNd7_YGuRampypivjlx9Yc3w9AEYuShaV6f7HGNl3Q.ZDJ2vfR7TwGtKFCj6zyZ_A'

JSON payload JWE for /ros endpoint You can find a detailed description of the individual elements in the technical documentation here.

Things to watch out for:

  • JWT Header of encrypted JWT MUST contain all fields especially cty, kid, enc a alg
  • structured_scope MUST contain a documentObject, signObject, or both
  • signObject MUST contain at least one field array element
  • elements outside the structured_scope (response_type, scope, client_id, …) contain common values as in the authentication flow. The values must correspond to the configuration of the application in the development portal.
  • the documet_id element MUST match the documentId value from the custom metadata of the PDF document
  • the document_hash element contains a byte hash of the content of the PDF document/file. The hash algorithm used MUST be specified in the element hash_alg (BankID recommends using the SHA512 algorithm, see JSON example).
  • the documet_uri element should point to where the document can be downloaded. In the current version, BankID is mandatory, but the site is not validated!
  • fields in the signObject element MUST have a defined priority that is unique as a number for each field
  • the maximum size of the key value in the signObject is 255 characters
  • the maximum size of the value element in signObject is 1024 characters

1.1 Sign Area

Suppose it is required to create a visual signature in the PDF as an embedded rectangle. In that case, it is necessary to define the area in the PDF where the visual signature is to be generated. The sign area is a set of coordinates that defines the location and size of the rectangle with the sign on the desired page of the PDF document.

The individual coordinates are in points (pt or PostScript) corresponding to 1/72 inch. This is the default PDF resolution, which can be set differently for the document. The size of a standard A4 PDF is therefore 595 x 842 pt.

  • the minimum width of signArea (x-dist element) is 112 pt
  • the minimum height of signArea (y-dist element) is 37 pt
  • the maximum width of signArea is 198 pt
  • the maximum height of signArea is 50 pt

Pages in the PDF are numbered from 0. If it is required to place a signature on the first page of the document, it is necessary to state the value 0 in the page element.

ATTENTION if it is not possible to place a rectangle in the document (eg, because the specified page does not exist or the area does not meet the conditions), the signature will be introduced into the PDF as non-visual.

Example of correctly filled in JSON payload for /ros request:

{
  "max_age": 3600,
  "ui_locales": "cs",
  "scope": "profile.name profile.titles openid profile.birthdate profile.addresses profile.legalstatus profile.email",
  "response_type": "code",
  "structured_scope": {
    "documentObject": {
      "document_title": "BankID Consent Document",
      "document_size": 68000,
      "document_subject": "Tribute to BankID",
      "document_language": "cs.CZ",
      "document_id": "BID001",
      "document_author": "Bankovni identita, a.s",
      "document_hash": "b2f50bbdeffbb3f0a34e426eee34f006fbbeebe001921eef46eeeeda3a9b27bde1d8b24b95b5db56a9ab27fa7157c0e8cb9bd7ef61d574f3c68d03eb127ff402",
      "document_read_by_enduser": true,
      "hash_alg": "2.16.840.1.101.3.4.2.3",
      "document_created": "2021-08-25T11:46:53+02:00",
      "sign_area": {
        "x-dist": 140,
        "x-coordinate": 320,
        "y-dist": 40,
        "y-coordinate": 400,
        "page": 0
      },
      "document_uri": "https://bankid.cz/documents?document_id=da17ca76-3257-4830-a588-1a84aac69697"
    },
    "signObject": {
      "fields": [
        {
          "priority": 1,
          "value": "Udeleni souhlasu s necim a k necemu",
          "key": "Ano souhlasim"
        }
      ]
    }
  },
  "txn": "455203fe-2db7-4177-b2a0-d6e2e126b2c9",
  "state": "H4YMSE8zcLS-xXLR7ZZ-toUcrYGeMLBLB9BbCtAo-2o",
  "nonce": "1jZ2YXn0kAa0Jfnn7Fig8Gz-wc_GBaQgDVzYtdXTkmI",
  "client_id": "d0cba9e6-ffff-487c-ffff-56395480c342"
}

If the request to /ros endpoint contains a documentObject definition, the response element upload_uri will be part of it, which must be used to upload the document.

Example response to /ros endpoint:

{
  "exp": 1632831257,
  "request_uri": "urn:uuid:da1fa559-5af4-492e-ffff-ab55e687df70",
  "upload_uri": "https://api.oidc.bankid.cz/test/dev-portal-fileservice/api/v1/files/prepared/52f9dbb1-9f4e-ffff-8f14-d13e224f5ab4"
}

2. Upload PDF

From the response to POST /ros endpoint we get upload_uri, which is unique for this authorization flow and is intended for upload a PDF document specified in the previous /ros request.

Things to watch out for:

  • documentId in the PDF metadata MUST be the same as the document_id specified in the previous /ros request
  • the hash of the uploaded document MUST be the same as the document_hash element during the last /ros request
  • the document is uploaded as a POST form-data

Example of document upload:

curl --location --request POST 'https://api.oidc.bankid.cz/test/dev-portal-fileservice/api/v1/files/prepared/52f9dbb1-9f4e-ffff-8f14-d13e224f5ab4' \
--form 'file=@"/C:/Files/signin.pdf"'

3. Authorization flow

If a document authorization request is registered via the /ros endpoint and a PDF document is uploaded (if the document is part of a signature request), it is possible to start the authorization flow.

The authorization flow takes place in the end user's browser environment. The link to start the authorization can be obtained from the BankID discovery service or read from the application settings in the Developer Portal (credentials tab after expanding the OIDC Discovery area in the "Authorize sign endpoint" item).

To build an authorization link, you will need:

  • Any application redirect_uri. One of the configured in the developer portal environment.
  • request_uri from response to request /ros endpoint. The validity of this uri is limited. See exp element in response to /ros.

Example of authorization line:

https://oidc.sandbox.bankid.cz/auth?redirect_uri=https://my.application.com/callback&request_uri=urn:uuid:da1fa559-5af4-492e-ffff-ab55e687df70

For proper authorization function (signing), we recommend using code_grant authorization flow.

The result of the authorization flow is a callback with code or tokens. The exchange of code for access_token and id_token takes place in the same way as for authentication flow. The link to download the signed document is part of the id_token as a document_uri element.

The validity of the PDF download link in document_uri is limited in time.

Example body of id_token JWT:

{
  "sub": "41f382d2-7cea-402f-97b4-afd864390b9c",
  "name": "John Doe",
  "exp": 1612258710,
  "iat": 1516239022,
  "iss": "https://idp.example.com",
  "sid": "41f382d2-7cea-402f-97b4-afd864390b9c",
  "aud": "https://rp.example.com/resource",
  "nonce": "gH4FFacc81",
  "acr": "loa3",
  "structured_scope": {
    "documentObject": {
      "document_id": "'7159534b-3b88-4f29-866b-9e83489d3053",
      "document_hash": "a93e305306c7a52ac2ccc55b83f197ea8e02b0ce6b317f53ae8e038586f88197",
      "hash_alg": "2.16.840.1.101.3.4.2.3",
      "document_title": "Smlouva o smlouvě budoucí",
      "document_subject": "Smlouva s společností ACME",
      "document_language": "en.EN",
      "document_created": "2020-06-24T08:54:11+00:00",
      "document_author": "Orange SK",
      "document_size": "1250000",
      "document_uri": "https://rp.net/documents?document_id=7e766e94-eb62-11ea-adc1-0242ac120002",
      "sign_area": {
        "page": 1,
        "x-coordinate": 10,
        "y-coordinate": 100,
        "x-dist": 35,
        "y-dist": 25
      }
    }
  }
}

Please note that BankID doesn't and cannot verify that document was signed by the person that should sign this document. Personal data of signatory person can be found in the certificate. Structure of certificate is below.

We also add serial number, and we keep this in immutable record for future proofing for validity of signature.

Please note that set of these objects can grow. Also, it's possible to combine more objects together in one request henceforth end user can authorize more actions in one bulk.

Requirements on documents

Following section describes requirements on documents which BanKID accepts for signatures

  • Document MUST be in PDF/A format, other formats are not accepted
  • Document CAN have signatures, document MUST NOT be locked in order to prevent changes. If document is locked BankID can't attach signature to document.
  • Document SHOULD have signature plane where BankID can place digital signature visualization. Specification of such area is manadatory.
  • Document MUST have same metadata as metadata sent through API

General notes on behavior of authorization

  • You can initiate authorization flow for anonymous user. If such flow is initiated BankID is initiating standard OIDC authentication flow.
  • You can also require for anonymous user to use remote authorization - meaning authorization flow is started without end-user's input and end-user authentication and authorization is executed asynchronously i.e. document signature with insurance agents or with utilities. See following sequence diagram:

  • For purposes of remote authorization or anonymous flow you MAY also provide an id_token (even old and expired) in /ros resource to prevent authentication of client and directly initiate authorization flow.
  • If you initiate authorization flow for authenticated user i.e. provide access token with granted scope, this end-user will be REQUIRED to use same bank to provide consent with adequate identity method.

Authorization server requirements

Following requirements must be met by you in general behavior and are enforced by BankID API

  • shall support only confidential clients;
  • shall require the request object to contain an exp claim; and
  • shall require explicit consent by the user to authorize the requested scope if it has not been previously authorized;
  • shall return token responses that conform to section 4.1.4 of [RFC6749];
  • shall return the list of granted scopes with the issued access token;
  • shall require the redirect URIs to use the https scheme;

Security considerations

Usage of authorization flow is bounded by general security guidelines.

General

Following rules SHALL be followed for both client and authorization server JWS algorithms

SHALL use PS256 or ES256 algorithms;
SHALL not use algorithms that use RSASSA-PKCS1-v1_5 (e.g. RS256);
SHALL not use none;

Certificates and policies

BankID is for each usage generating new certificate for end user based on identity proofing with assurance level substantial. Details can be found in certification policy. Fo technical purposes of verification of identity, structure of certificate is following:

CN= title_prefix + " " +firstname +" "+last name
givenName= firstname
sn= last name
O= name of verifying bank 
C= country of residence
Pseudonym = sub - id of end user issued by BankID for you, MUST match sub in ID token
X509v3 Extensions:
dateOfBirth = year of birth (19710101120000Z where 1971 is year of birth) in subjectDirectoryAttributes

We also add serial number, and we keep this as immutable record for future proofing of validity of signature.

Authorization server

Following guidelines must be followed by you to ensure security, and these are enforce by BankID APIs.

  • shall authenticate the confidential client at the token endpoint and private_key_jwt as specified in section 9 of [OIDC];
  • shall require a key of size 256 bits or larger for elliptic curve algorithms used for the client authentication;
  • shall require the redirect URIs to be pre-registered;
  • shall require the redirect_uri parameter in the authorization request;
  • shall require the value of redirect_uri to exactly match one of the pre-registered redirect URIs;
  • shall require user authentication at LoA 3 as defined in [X.1254].
  • shall require the response_type values code id_token or code id_token token;

Cookies are bad for your teeth but good for BankID • Cookie policy