├── .gitignore ├── src └── doc │ ├── images │ ├── abis.png │ ├── logo.pdf │ ├── logo2.pdf │ ├── components.pdf │ ├── UIN_generator.png │ ├── civil_registry.png │ ├── enrollment_client.png │ ├── enrollment_server.png │ ├── population_registry.png │ ├── third_party_services.png │ ├── credential_management_system.png │ ├── custom.css │ └── logo.svg │ ├── appendices │ ├── index.rst │ └── versions.rst │ ├── annexes │ ├── index.rst │ ├── dataformat.rst │ ├── glossary.rst │ ├── references.rst │ └── license.rst │ ├── 07 - technical specs.rst │ ├── index.rst │ ├── 05 - interfaces.rst │ ├── technical │ ├── uin.rst │ ├── abis.rst │ ├── pr.rst │ ├── 3rdparty.rst │ ├── cms.rst │ ├── enrollment.rst │ ├── dataaccess.rst │ └── notification.rst │ ├── bibliography.rst │ ├── functional │ ├── _uin.rst │ ├── _notification.rst │ ├── _3rdparty.rst │ ├── _dataaccess.rst │ ├── _cms.rst │ ├── _enrollment.rst │ ├── _pr.rst │ └── _abis.rst │ ├── yaml │ ├── uin.yaml │ ├── notification.yaml │ └── dataaccess.yaml │ ├── conf.py │ ├── 01 - intro.rst │ └── 06 - building blocks.rst ├── OSIA_Colour_Logo_RGB_400px.png ├── requirements.txt ├── .readthedocs.yml ├── HOWTO.md ├── README.md └── LICENSE /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .vscode/settings.json 3 | src/doc/_build/* 4 | .DS_Store 5 | target/ 6 | __pycache__ 7 | -------------------------------------------------------------------------------- /src/doc/images/abis.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/abis.png -------------------------------------------------------------------------------- /src/doc/images/logo.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/logo.pdf -------------------------------------------------------------------------------- /src/doc/images/logo2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/logo2.pdf -------------------------------------------------------------------------------- /OSIA_Colour_Logo_RGB_400px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/OSIA_Colour_Logo_RGB_400px.png -------------------------------------------------------------------------------- /src/doc/images/components.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/components.pdf -------------------------------------------------------------------------------- /src/doc/images/UIN_generator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/UIN_generator.png -------------------------------------------------------------------------------- /src/doc/images/civil_registry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/civil_registry.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx==7.4.7 2 | Pillow 3 | sphinxcontrib-httpdomain==1.8.1 4 | sphinxcontrib-plantuml==0.30 5 | sc-oa==0.7.0.16 6 | -------------------------------------------------------------------------------- /src/doc/images/enrollment_client.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/enrollment_client.png -------------------------------------------------------------------------------- /src/doc/images/enrollment_server.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/enrollment_server.png -------------------------------------------------------------------------------- /src/doc/images/population_registry.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/population_registry.png -------------------------------------------------------------------------------- /src/doc/images/third_party_services.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/third_party_services.png -------------------------------------------------------------------------------- /src/doc/appendices/index.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _chapter-appendices: 3 | 4 | Appendices 5 | ========== 6 | 7 | .. toctree:: 8 | 9 | versions 10 | -------------------------------------------------------------------------------- /src/doc/images/credential_management_system.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SecureIdentityAlliance/osia/HEAD/src/doc/images/credential_management_system.png -------------------------------------------------------------------------------- /src/doc/annexes/index.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _chapter-annexes: 3 | 4 | Annexes 5 | ======= 6 | 7 | .. toctree:: 8 | 9 | glossary 10 | dataformat 11 | references 12 | license 13 | -------------------------------------------------------------------------------- /src/doc/07 - technical specs.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _chapter-tech-specs: 3 | 4 | Technical Specifications 5 | ======================== 6 | 7 | .. toctree:: 8 | 9 | technical/notification 10 | technical/uin 11 | technical/dataaccess 12 | technical/enrollment 13 | technical/pr 14 | technical/abis 15 | technical/cms 16 | technical/3rdparty 17 | -------------------------------------------------------------------------------- /src/doc/index.rst: -------------------------------------------------------------------------------- 1 | 2 | |project| Specification 3 | ======================= 4 | 5 | .. toctree:: 6 | :maxdepth: 3 7 | :numbered: 8 | 9 | 01 - intro 10 | 02 - functional 11 | 03 - security 12 | 05 - interfaces 13 | 06 - building blocks 14 | 07 - technical specs 15 | annexes/index 16 | appendices/index 17 | bibliography 18 | -------------------------------------------------------------------------------- /src/doc/05 - interfaces.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _chapter-interfaces: 3 | 4 | ========== 5 | Interfaces 6 | ========== 7 | 8 | The chapter below describes the specifications of all OSIA interfaces and related services. 9 | 10 | .. include:: functional/_notification.rst 11 | 12 | .. include:: functional/_dataaccess.rst 13 | 14 | .. include:: functional/_uin.rst 15 | 16 | .. include:: functional/_enrollment.rst 17 | 18 | .. include:: functional/_pr.rst 19 | 20 | .. include:: functional/_abis.rst 21 | 22 | .. include:: functional/_cms.rst 23 | 24 | .. include:: functional/_3rdparty.rst 25 | -------------------------------------------------------------------------------- /src/doc/technical/uin.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-uin: 3 | 4 | UIN Management 5 | -------------- 6 | 7 | This is version :openapi:version:`../yaml/uin.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `uin.yaml <../uin.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/uin.yaml}{uin.yaml} 16 | 17 | .. sidebar:: UIN Management 18 | 19 | .. openapi:toc:: ../yaml/uin.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/uin.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | -------------------------------------------------------------------------------- /src/doc/bibliography.rst: -------------------------------------------------------------------------------- 1 | Bibliography 2 | ============ 3 | 4 | [b-JSON Web Token] 5 | IETF RFC 8725, *JSON Web Token Best Current Practices*, 6 | 7 | https://datatracker.ietf.org/doc/html/rfc8725 8 | 9 | [b-OpenAPI] 10 | OpenAPI Specification v3.0.3 (2020), 11 | 12 | https://spec.openapis.org/oas/v3.0.3 13 | 14 | [b-WSQ] 15 | NIST; FBI; *Los Alamos Natinal Laboratory. Wavelet Scalar Quantization algorithm 2: PDF 2.0*, 16 | 17 | `https://www.nist.gov/system/files/documents/2020/09/03/11-wsq_bradley_brislawn_standard_ieee_iscs_-_19940530.pdf `_ 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/doc/technical/abis.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-abis: 3 | 4 | Biometrics 5 | ---------- 6 | 7 | This is version :openapi:version:`../yaml/abis.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `abis.yaml <../abis.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/abis.yaml}{abis.yaml} 16 | 17 | .. sidebar:: Biometrics Services 18 | 19 | .. openapi:toc:: ../yaml/abis.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/abis.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | :entities: 29 | 30 | Data Model 31 | """""""""" 32 | 33 | .. openapi:model:: ../yaml/abis.yaml 34 | 35 | -------------------------------------------------------------------------------- /src/doc/technical/pr.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-pr: 3 | 4 | Population Registry Management 5 | ------------------------------ 6 | 7 | This is version :openapi:version:`../yaml/pr.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `pr.yaml <../pr.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/pr.yaml}{pr.yaml} 16 | 17 | .. sidebar:: Population Registry Services 18 | 19 | .. openapi:toc:: ../yaml/pr.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/pr.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | :entities: 29 | 30 | Data Model 31 | """""""""" 32 | 33 | .. openapi:model:: ../yaml/pr.yaml 34 | -------------------------------------------------------------------------------- /src/doc/technical/3rdparty.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-3rdparty: 3 | 4 | Third Party Services 5 | -------------------- 6 | 7 | This is version :openapi:version:`../yaml/3rdparty.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `3rdparty.yaml <../3rdparty.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/3rdparty.yaml}{3rdparty.yaml} 16 | 17 | .. sidebar:: Third Party Services 18 | 19 | .. openapi:toc:: ../yaml/3rdparty.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | '''''''' 24 | .. openapi:: ../yaml/3rdparty.yaml 25 | :examples: 26 | :group_examples: 27 | :entities: 28 | 29 | Data Model 30 | '''''''''' 31 | 32 | .. openapi:model:: ../yaml/3rdparty.yaml 33 | 34 | -------------------------------------------------------------------------------- /src/doc/technical/cms.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-cms: 3 | 4 | Credential Services 5 | ------------------- 6 | 7 | This is version :openapi:version:`../yaml/cms.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `cms.yaml <../cms.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/cms.yaml}{cms.yaml} 16 | 17 | .. sidebar:: Credential Services 18 | 19 | .. openapi:toc:: ../yaml/cms.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/cms.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | :entities: 29 | 30 | Data Model 31 | """""""""" 32 | 33 | .. openapi:model:: ../yaml/cms.yaml 34 | 35 | -------------------------------------------------------------------------------- /src/doc/technical/enrollment.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-enrollment: 3 | 4 | Enrollment 5 | ---------- 6 | 7 | This is version :openapi:version:`../yaml/enrollment.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `enrollment.yaml <../enrollment.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/enrollment.yaml}{enrollment.yaml} 16 | 17 | .. sidebar:: Enrollment Services 18 | 19 | .. openapi:toc:: ../yaml/enrollment.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/enrollment.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | :entities: 29 | 30 | Data Model 31 | """""""""" 32 | 33 | .. openapi:model:: ../yaml/enrollment.yaml 34 | 35 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for Sphinx projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | # Required 5 | version: 2 6 | 7 | # Set the OS, Python version and other tools you might need 8 | build: 9 | os: ubuntu-24.04 10 | tools: 11 | python: "3.12" 12 | apt_packages: 13 | - plantuml 14 | - inkscape 15 | 16 | # Build documentation in the "docs/" directory with Sphinx 17 | sphinx: 18 | configuration: src/doc/conf.py 19 | 20 | # Optionally build your docs in additional formats such as PDF and ePub 21 | formats: 22 | - pdf 23 | 24 | # Optional but recommended, declare the Python requirements required 25 | # to build your documentation 26 | # See https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html 27 | python: 28 | install: 29 | - requirements: ./requirements.txt 30 | -------------------------------------------------------------------------------- /src/doc/functional/_uin.rst: -------------------------------------------------------------------------------- 1 | 2 | UIN Management 3 | -------------- 4 | 5 | See :ref:`annex-interface-uin` for the technical details of this interface. 6 | 7 | Services 8 | """""""" 9 | 10 | .. py:function:: generateUIN(attributes, transactionID) 11 | :noindex: 12 | 13 | Generate a new UIN. 14 | 15 | **Authorization**: ``uin.generate`` 16 | 17 | :param list[(str,str)] attributes: A list of pair (attribute name, value) that can be used to allocate a new UIN 18 | :param str transactionID: A free text used to track the system activities related to the same transaction. 19 | :return: a new UIN or an error if the generation is not possible 20 | 21 | This service is synchronous. 22 | 23 | .. uml:: 24 | :caption: ``generateUIN`` Sequence Diagram 25 | :scale: 50% 26 | 27 | hide footbox 28 | participant "CR" as CR 29 | participant "PR" as PR 30 | participant "UIN Generator" as UIN 31 | 32 | note over CR,UIN: CR can request a new UIN 33 | CR -> UIN: generateUIN([attributes]) 34 | UIN -->> CR: UIN 35 | 36 | note over PR,UIN: PR can request a new UIN 37 | PR -> UIN: generateUIN([attributes]) 38 | UIN -->> PR: UIN 39 | -------------------------------------------------------------------------------- /src/doc/annexes/dataformat.rst: -------------------------------------------------------------------------------- 1 | 2 | Data Format 3 | =========== 4 | 5 | The following data formats are used in OSIA: 6 | 7 | .. list-table:: OSIA Data Formats 8 | :header-rows: 1 9 | :widths: 20 30 50 10 | 11 | * - Data 12 | - Format 13 | - Description 14 | 15 | * - Service Description 16 | - `OpenAPI 3.0.x `_ 17 | - All OSIA interfaces are described using OpenAPI 3.0.x format. OpenAPI can use json or YAML file, YAML is preferred for its readability. 18 | 19 | * - Service Payload 20 | - `json `_ 21 | - json has builtin format for string, integer, floating number, boolean, as well as list and dictionary. 22 | json is widely used and supported by many different languages and frameworks, making it ideal to favor interoperability. 23 | 24 | * - Date & Time 25 | - `iso8601 `_ 26 | - The iso8601 defines format for date and date and time. It supports local time as well as UTC time. 27 | iso8601-2, dated 2019, can be used to represent dates with unknown part. 28 | 29 | * - Biometric Images 30 | - JPEG, JPEG2000, PNG, WSQ, ISO19794 31 | - Images can be transfered as a URL or can be embedded in the json. When embedded they are encoded in base64. 32 | It is highly recommended to use a widely used format such as JPEG, PNG, or WSQ for fingerprints. 33 | ISO19794 is also recommended when possible. 34 | 35 | * - Documents 36 | - JPEG, PNG, PDF 37 | - Documents captured during enrollment can use the JPEG format for monopage document. PDF is also 38 | widely recognized and very convenient to transfer both images and text in multipage documents. 39 | 40 | 41 | -------------------------------------------------------------------------------- /src/doc/images/custom.css: -------------------------------------------------------------------------------- 1 | div.document { 2 | width: 95%; 3 | max-width: none; 4 | } 5 | 6 | body { 7 | font-family: "Roboto", Corbel, Avenir, "Lucida Grande", "Lucida Sans", sans-serif; 8 | } 9 | 10 | pre { 11 | font-family: "Fira Mono", Consolas, Menlo, Monaco, "Courier New", Courier, monospace; 12 | font-variant-ligatures: no-common-ligatures; 13 | } 14 | 15 | div.body h1, div.body h2, div.body h3, div.body h4, div.body h5, div.body h6, 16 | div.sphinxsidebar h1, div.sphinxsidebar h2, div.sphinxsidebar h3, div.sphinxsidebar input { 17 | font-family: "Roboto", Corbel, Avenir, "Lucida Grande", "Lucida Sans", sans-serif; 18 | } 19 | 20 | div.bodywrapper { 21 | margin: 0 0 0 300px; 22 | } 23 | 24 | div.sphinxsidebar { 25 | width: 300px; 26 | } 27 | 28 | aside.sidebar { 29 | width: 20%; 30 | } 31 | 32 | div.body { 33 | max-width: none; 34 | } 35 | 36 | div.body p, ol > li, div.body td { 37 | text-align: justify; 38 | } 39 | 40 | 41 | img, div.figure { 42 | margin: 0 !important 43 | } 44 | 45 | ul > li { 46 | text-align: justify; 47 | } 48 | 49 | ul > li > p { 50 | margin-bottom: 0; 51 | 52 | } 53 | 54 | 55 | ol > li > p { 56 | margin-bottom: 0; 57 | 58 | } 59 | 60 | div.body code.descclassname { 61 | display: none 62 | } 63 | 64 | .wy-table-responsive table td { 65 | white-space: normal !important; 66 | } 67 | 68 | .wy-table-responsive { 69 | overflow: visible !important; 70 | } 71 | 72 | div.toctree-wrapper.compound > ul > li { 73 | margin: 0; 74 | padding: 0 75 | } 76 | 77 | code.docutils.literal { 78 | background-color: #ECF0F3; 79 | padding: 0 1px; 80 | } 81 | 82 | div#changelog-history h3{ 83 | margin-top: 10px; 84 | } 85 | 86 | div#changelog-history h2{ 87 | font-style: italic; 88 | font-weight: bold; 89 | } 90 | 91 | table.field-list { 92 | width: 100%; 93 | } 94 | 95 | table.field-list colgroup .field-body { 96 | width: 85%; 97 | } 98 | -------------------------------------------------------------------------------- /HOWTO.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | This is a small guide for the contributors, explaining how to change and build the OSIA documentation. 4 | 5 | ## Setup your build environment 6 | 7 | This OSIA documentation is written in reStruturedText and built with Sphinx. There is no specific 8 | tool to write it, just any text editor will do and many have a plugin to help and write reST syntax. 9 | 10 | To build the documentation and check it before pushing it in Github, Sphinx must be installed. 11 | 12 | 1. Install Python 3.x (x>=9). Python 3.12, the latest version, is working fine. 13 | 2. Install Java 17. Java is required for PlantUML. 14 | 3. Install PlantUML version 1.2024.7 (available from http://plantuml.com/download). 15 | The command ``plantuml`` must be accessible. 16 | 17 | 4. (optional) Create a Python virtual environment: 18 | 19 | - Install virtualenv 20 | - Run: 21 | 22 | ```shell 23 | virtualenv -p python py4osia 24 | source py4osia/bin/activate 25 | ``` 26 | 5. Install Sphinx and the required dependencies: 27 | 28 | ```shell 29 | pip install -r requirements.txt 30 | ``` 31 | 32 | 6. Fork the OSIA repository and clone locally your fork 33 | 7. Build the documentation running: 34 | 35 | ```shell 36 | sphinx-build -b html src/doc target/html 37 | ``` 38 | ## Edit the documentation 39 | 40 | The OSIA documentation is organized in text files, each file corresponding to a chapter. 41 | 42 | Sphinx syntax is explained here: http://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html 43 | You can also check http://www.sphinx-doc.org/en/master/usage/quickstart.html. 44 | 45 | To add a new API in OSIA: 46 | 47 | 1. Isolate the functional description in a new file in directory `src/doc/functional`. 48 | There is already one file per interface. Just copy & paste one to bootstrap a new one. 49 | 2. Reference (include) this functional description in the chapters 5. 50 | 3. Add the corresponding OpenAPI v3 YAML file in `src/doc/yaml` and add a file in `src/doc/07 - technical specs.rst` 51 | referencing the yaml. 52 | Look for samples in the existing files. 53 | 54 | -------------------------------------------------------------------------------- /src/doc/annexes/glossary.rst: -------------------------------------------------------------------------------- 1 | 2 | Glossary 3 | ======== 4 | 5 | .. glossary:: 6 | 7 | **ABIS** 8 | Automated Biometric Identification System 9 | 10 | **CR** 11 | Civil Registry. The system in charge of the continuous, permanent, compulsory and universal recording 12 | of the occurrence and characteristics of vital events pertaining to the population, as provided 13 | through decree or regulation in accordance with the legal requirements in each country. 14 | 15 | **CMS** 16 | Credential Management System 17 | 18 | **Credential** 19 | A document, object, or data structure that vouches for the identity of a person through some method of 20 | trust and authentication. Common types of identity credentials include - but are not limited to — ID cards, 21 | certificates, numbers, passwords, or SIM cards. A biometric identifier can also be used as a credential 22 | once it has been registered with the identity provider. 23 | 24 | (Source: `ID4D Practioner's Guide `_) 25 | 26 | **Encounter** 27 | Event in which the client application interacts with 28 | a person resulting in data being collected during or 29 | about the encounter. An encounter is characterized by 30 | an identifier and a type (also called purpose in some 31 | context). 32 | 33 | (Source: ISO-30108-1) 34 | 35 | **Functional systems and registries** 36 | Managing data including voter rolls, land registry, vehicle registration, passport, residence registry, 37 | education, health and benefits. 38 | 39 | **Gallery** 40 | Group of persons related by a common purpose, designation, or status. 41 | Example: a watch list or a set of persons entitled to a certain benefit. 42 | 43 | (Source: ISO-30108-1) 44 | 45 | **HTTP Status Codes** 46 | The HTTP Status Codes are used to indicate the status of the executed operation. The available status codes are 47 | described by `RFC 7231 `_ and in the 48 | `IANA Status Code Registry `_. 49 | 50 | **Mime Types** 51 | Mime type definitions are spread across several resources. The mime type definitions should be in compliance with 52 | `RFC 6838 `_. 53 | 54 | Some examples of possible mime type definitions: 55 | 56 | :: 57 | 58 | text/plain; charset=utf-8 59 | application/json 60 | 61 | **OSIA** 62 | Open Standard Identity APIs 63 | 64 | **PR** 65 | Population Registry. The system in charge of the recording of selected information pertaining to each member 66 | of the resident population of a country. 67 | 68 | **UIN** 69 | Unique Identity Number 70 | 71 | **PQC** 72 | Post Quantum Cryptography 73 | -------------------------------------------------------------------------------- /src/doc/yaml/uin.yaml: -------------------------------------------------------------------------------- 1 | 2 | # (c) Secure Identity Alliance 3 | 4 | openapi: 3.0.0 5 | info: 6 | description: | 7 | The OSIA UIN Interface. 8 | 9 | Change log: 10 | 11 | - 1.2.0: 12 | - Add error structure on 400 errors 13 | - Force additionalProperties to false when extension is not allowed 14 | - Add transactionId as a parameter (mandatory) 15 | - 1.1.0: 16 | - Addition of security 17 | - 1.0.0: Initial version 18 | 19 | title: OSIA UIN Interface 20 | version: 1.2.0 21 | license: 22 | name: SIA 23 | url: "https://raw.githubusercontent.com/SecureIdentityAlliance/osia/master/LICENSE" 24 | servers: 25 | - url: https://uin.com/ 26 | paths: 27 | /v1/uin: 28 | post: 29 | description: | 30 | Request the generation of a new UIN. 31 | The request body should contain a list of attributes and their value, formatted as a json dictionary. 32 | operationId: generateUIN 33 | security: 34 | - BearerAuth: [uin.generate] 35 | parameters: 36 | - name: transactionId 37 | in: query 38 | description: The id of the transaction 39 | required: true 40 | schema: 41 | type: string 42 | requestBody: 43 | description: A set of attributes for the person 44 | content: 45 | application/json: 46 | schema: 47 | $ref: '#/components/schemas/Attributes' 48 | example: 49 | firstName: John 50 | lastName: Doo 51 | dateOfBirth: "1984-11-19" 52 | responses: 53 | 200: 54 | description: UIN is generated 55 | content: 56 | application/json: 57 | schema: 58 | type: string 59 | example: 60 | '"1235567890"' 61 | 400: 62 | description: Unexpected error 63 | content: 64 | application/json: 65 | schema: 66 | $ref: '#/components/schemas/Error' 67 | 401: 68 | description: Client must be authenticated 69 | 403: 70 | description: Service forbidden 71 | 500: 72 | description: Unexpected error 73 | content: 74 | application/json: 75 | schema: 76 | $ref: '#/components/schemas/Error' 77 | 78 | components: 79 | securitySchemes: 80 | BearerAuth: 81 | type: http 82 | scheme: bearer 83 | bearerFormat: JWT 84 | schemas: 85 | Error: 86 | type: object 87 | required: 88 | - code 89 | - message 90 | properties: 91 | code: 92 | type: integer 93 | format: int32 94 | message: 95 | type: string 96 | additionalProperties: false 97 | Attributes: 98 | type: object 99 | additionalProperties: 100 | oneOf: 101 | - type: string 102 | - type: integer 103 | - type: number 104 | - type: boolean 105 | # Or ?: 106 | #additionalProperties: 107 | # type: string 108 | -------------------------------------------------------------------------------- /src/doc/appendices/versions.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _osia-versions-ref: 3 | 4 | Appendix I 5 | ========== 6 | 7 | .. only:: itu 8 | 9 | (This appendix does not form an integral part of this Recommendation.) 10 | 11 | There is a version for each interface. 12 | Each interface can be referenced as follows: 13 | 14 | ``OSIA v. [version] - [interface name] v. [version number]`` 15 | 16 | For instance below is the string to reference the *Notification* interface: 17 | 18 | ``OSIA v. 6.1 - Notification v. 1.2.0`` 19 | 20 | Below is the complete list of available interfaces with related versions. 21 | 22 | Versions published by Secure Identity Alliance GEIE, located in Paris, France: 23 | 24 | .. list-table:: OSIA Services Versions (Old Licence) 25 | :header-rows: 2 26 | :widths: 30 10 10 10 10 10 10 27 | 28 | * - OSIA Release 29 | - 1.0.0 30 | - 2.0.0 31 | - 3.0.0 32 | - 4.1.0 33 | - 5.0.0 34 | - 6.0.0 35 | * - OSIA Release Date 36 | - mar-2019 37 | - jun-2019 38 | - nov-2019 39 | - jul-2020 40 | - dec-2020 41 | - dec-2021 42 | * - **Notification** 43 | - . 44 | - **1.0.0** 45 | - 1.0.0 46 | - **1.1.0** 47 | - **1.2.0** 48 | - 1.2.0 49 | * - **UIN Management** 50 | - **1.0.0** 51 | - 1.0.0 52 | - 1.0.0 53 | - **1.1.0** 54 | - **1.2.0** 55 | - 1.2.0 56 | * - **Data Access** 57 | - **1.0.0** 58 | - 1.0.0 59 | - 1.0.0 60 | - **1.1.0** 61 | - **1.3.0** 62 | - 1.3.0 63 | * - **Enrollment Services** 64 | - . 65 | - . 66 | - . 67 | - **1.0.0** 68 | - **1.1.0** 69 | - **1.2.0** 70 | * - **Population Registry Services** 71 | - . 72 | - . 73 | - 1.0.0 74 | - 1.2.0 75 | - 1.3.0 76 | - 1.4.0 77 | * - **Biometrics Services** 78 | - . 79 | - **1.0.0** 80 | - **1.1.0** 81 | - **1.3.0** 82 | - **1.4.0** 83 | - **1.5.0** 84 | * - **Credential Services** 85 | - . 86 | - . 87 | - . 88 | - **1.0.0** 89 | - **1.1.0** 90 | - **1.2.0** 91 | * - **Third Party Services** 92 | - . 93 | - . 94 | - . 95 | - . 96 | - **1.0.0** 97 | - **1.1.0** 98 | 99 | Versions published by Secure Identity Alliance ASBL, located in Brussels, Belgium, 100 | under a new licence named the "OSIA License". 101 | 102 | .. list-table:: OSIA Services Versions (New Licence) 103 | :header-rows: 2 104 | :widths: 30 10 10 105 | 106 | * - OSIA Release 107 | - 6.1.0 108 | - 7.0 109 | * - OSIA Release Date 110 | - dec-2022 111 | - dec-2025 112 | * - **Notification** 113 | - 1.2.0 114 | - 1.2.0 115 | * - **UIN Management** 116 | - 1.2.0 117 | - 1.2.0 118 | * - **Data Access** 119 | - 1.3.0 120 | - 1.3.0 121 | * - **Enrollment Services** 122 | - 1.2.1 123 | - **1.3.0** 124 | * - **Population Registry Services** 125 | - 1.4.1 126 | - **1.5.0** 127 | * - **Biometrics Services** 128 | - 1.5.1 129 | - **1.6.0** 130 | * - **Credential Services** 131 | - 1.2.1 132 | - **1.3.0** 133 | * - **Third Party Services** 134 | - 1.1.1 135 | - **1.2.0** 136 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OSIA Initiative 2 | 3 | _A digital public good, OSIA is an open standard set of interfaces (APIs) that enables seamless connectivity between building blocks of the identity management ecosystem - independent of technology, solution architecture or vendor._ 4 | 5 | [![Documentation Status](https://readthedocs.org/projects/osia/badge/?version=latest)](https://osia.readthedocs.io/en/latest/?badge=latest) 6 | 7 | ![SIA Logo](OSIA_Colour_Logo_RGB_400px.png "Secure Identity Alliance") 8 | 9 | ## Presentation 10 | 11 | In 2019, the non-for-profit Secure Identity Alliance (SIA)[^1], launched the global OSIA initiative. 12 | 13 | The aim of the OSIA Initiative is to develop a framework of open standards for the interoperability of foundational identity systems. 14 | Around the globe, legal or official identity is the foundation of national security, social protection, and economic growth strategies. 15 | 16 | As the identity market matures, technologies like digital identity, biometrics and cloud platforms are transforming the identity landscape. Making it possible to: 17 | * enable national identity schemes that are truly inclusive and serve the needs of all stakeholders 18 | * initiate the delivery of innovative digital public and private services. 19 | 20 | To capture this opportunity without undue cost or time-consuming integration effort, governments need to be free to evolve, adapt, modernize, and add to their systems with confidence – and without fear of future compatibility issues. 21 | 22 | Until recently, however, the initiation of highly functional and interoperable foundational identity systems that are easy to upgrade or change has been constrained by a siloed approach and lack of standardization that made it difficult to connect registries or exchange, consult, or update data between systems. 23 | 24 | OSIA breaks silos and enables interoperability. 25 | 26 | It also enables the all-important government industry collaborations needed to create the frameworks that make it possible to build truly open, innovative and future-proofed national identity systems, OSIA is transforming how governments leverage identity to deliver real-world impacts for their citizens and national economies. 27 | 28 | [^1]: Secure Identity Alliance (SIA) is established as a non-profit association (N° 0785731573) pursuant to the Companies and Associations Code of 23 March 2019, published in the Belgian Official Gazette of 4 April 2019 with a registered office located in the Brussels-Capital Region. The disinterested goal of the non-profit association is to unify the ecosystem of identity (ID) and unlock the full power of identity so that people, economy, and society thrive. Representing ID actors and organisations active across the ID ecosystem and adjacent industries, the Association supports the development of the activities of its members across four broad pillars: Identity for Good, Outreach, Open Standards Development and Industry Services and Solutions. 29 | 30 | See also https://secureidentityalliance.github.io/ 31 | 32 | ## Building documentation 33 | 34 | OSIA documentation is written in reStruturedText and built with Sphinx. 35 | 36 | You can read the latest version on https://osia.readthedocs.io/en/latest/ 37 | 38 | To build it yourself, prepare your environment: 39 | 40 | ``` 41 | pip install Sphinx Pillow sphinxcontrib-httpdomain sphinxcontrib-plantuml sc-oa 42 | ``` 43 | 44 | UML diagrams are built with PlantUML and Java 8. They must be installed separately. 45 | 46 | Build: 47 | 48 | ``` 49 | sphinx-build -b html src/doc target/html 50 | ``` 51 | -------------------------------------------------------------------------------- /src/doc/technical/dataaccess.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-dataaccess: 3 | 4 | Data Access 5 | ----------- 6 | 7 | This is version :openapi:version:`../yaml/dataaccess.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `dataaccess.yaml <../dataaccess.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/dataaccess.yaml}{dataaccess.yaml} 16 | 17 | .. sidebar:: Data Access Services 18 | 19 | .. openapi:toc:: ../yaml/dataaccess.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/dataaccess.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | 29 | Data Model 30 | """""""""" 31 | 32 | .. _person-attributes: 33 | 34 | Person Attributes 35 | ''''''''''''''''' 36 | 37 | When exchanged in the services described in this document, the persons attributes 38 | will apply the following rules: 39 | 40 | .. list-table:: Person Attributes 41 | :header-rows: 1 42 | :widths: 20 30 50 43 | 44 | * - Attribute Name 45 | - Description 46 | - Format 47 | 48 | * - ``uin`` 49 | - Unique Identity Number 50 | - Text 51 | * - ``firstName`` 52 | - First name 53 | - Text 54 | * - ``lastName`` 55 | - Last name 56 | - Text 57 | * - ``spouseName`` 58 | - Spouse name 59 | - Text 60 | * - ``dateOfBirth`` 61 | - Date of birth 62 | - Date (iso8601). Example: ``1987-11-17`` 63 | * - ``placeOfBirth`` 64 | - Place of birth 65 | - Text 66 | * - ``gender`` 67 | - Gender 68 | - Number (iso5218). One of 0 (Not known), 1 (Male), 2 (Female), 9 (Not applicable) 69 | * - ``dateOfDeath`` 70 | - Date of death 71 | - Date (iso8601). Example: ``2018-11-17`` 72 | * - ``placeOfDeath`` 73 | - Place of death 74 | - Text 75 | * - ``reasonOfDeath`` 76 | - Reason of death 77 | - Text 78 | * - ``status`` 79 | - Status. Example: missing, wanted, dead, etc. 80 | - Text 81 | 82 | 83 | .. _matching-error: 84 | 85 | Matching Error 86 | '''''''''''''' 87 | 88 | A list of: 89 | 90 | .. list-table:: Matching Error Object 91 | :header-rows: 1 92 | :widths: 25 20 35 10 93 | 94 | * - Attribute 95 | - Type 96 | - Description 97 | - Mandatory 98 | 99 | * - ``attributeName`` 100 | - String 101 | - Attribute name (See :ref:`person-attributes`) 102 | - Yes 103 | 104 | * - ``errorCode`` 105 | - 32 bits integer 106 | - Error code. Possible values: ``0`` (attribute does not exist); ``1`` (attribute exists but does not match) 107 | - Yes 108 | 109 | .. _expression: 110 | 111 | Expression 112 | '''''''''' 113 | 114 | .. list-table:: Expression Object 115 | :header-rows: 1 116 | :widths: 25 20 35 10 117 | 118 | * - Attribute 119 | - Type 120 | - Description 121 | - Mandatory 122 | 123 | * - ``attributeName`` 124 | - String 125 | - Attribute name (See :ref:`person-attributes`) 126 | - Yes 127 | 128 | * - ``operator`` 129 | - String 130 | - Operator to apply. Possible values: ``<``, ``>``, ``=``, ``>=``, ``<=`` 131 | - Yes 132 | 133 | * - ``value`` 134 | - string, or integer, or boolean 135 | - The value to be evaluated 136 | - Yes 137 | 138 | .. _error: 139 | 140 | Error 141 | ''''' 142 | 143 | .. list-table:: Error Object 144 | :header-rows: 1 145 | :widths: 25 20 35 10 146 | 147 | * - Attribute 148 | - Type 149 | - Description 150 | - Mandatory 151 | 152 | * - ``code`` 153 | - 32 bits integer 154 | - Error code 155 | - Yes 156 | 157 | * - ``message`` 158 | - String 159 | - Error message 160 | - Yes 161 | 162 | -------------------------------------------------------------------------------- /src/doc/annexes/references.rst: -------------------------------------------------------------------------------- 1 | References 2 | ========== 3 | 4 | .. list-table:: References 5 | :widths: 20 80 6 | :stub-columns: 1 7 | 8 | * - [RFC2119] 9 | - Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119 10 | * - [RFC3230] 11 | - Instance Digests in HTTP. January 2002. URL: https://www.rfc-editor.org/rfc/rfc3230 12 | * - [RFC3339] 13 | - Date and Time on the Internet: Timestamps. July 2002. URL: https://www.rfc-editor.org/rfc/rfc3339 14 | * - [RFC4180] 15 | - Common Format and MIME Type for Comma-Separated Values (CSV) Files. October 2005. URL: https://www.rfc-editor.org/rfc/rfc4180 16 | * - [RFC5652] 17 | - Cryptographic Message Syntax (CMS). September 2009. URL: https://www.rfc-editor.org/rfc/rfc5652 18 | * - [RFC6750] 19 | - The OAuth 2.0 Authorization Framework: Bearer Token Usage. October 2012. URL: https://www.rfc-editor.org/rfc/rfc6750 20 | * - [RFC6838] 21 | - Media Type Specifications and Registration Procedures. January 2013. URL: https://www.rfc-editor.org/rfc/rfc6838 22 | * - [RFC7230] 23 | - Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. URL: https://www.rfc-editor.org/rfc/rfc7230 24 | * - [RFC7231] 25 | - Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. June 2014. URL: https://www.rfc-editor.org/rfc/rfc7231 26 | * - [RFC7396] 27 | - JSON Merge Patch. October 2014. URL: https://www.rfc-editor.org/rfc/rfc7396 28 | * - [RFC7515] 29 | - JSON Web Signature (JWS). May 2015. RFC. URL: https://tools.ietf.org/html/rfc7515 30 | * - [RFC7516] 31 | - JSON Web Encryption (JWE). May 2015. RFC. URL: https://tools.ietf.org/html/rfc7516 32 | * - [RFC7518] 33 | - JSON Web Algorithms (JWA). May 2015. RFC. URL: https://tools.ietf.org/html/rfc7518 34 | * - [RFC7519] 35 | - JSON Web Token (JWT). May 2015. RFC. URL: https://tools.ietf.org/html/rfc7519 36 | * - [RFC8785] 37 | - JSON Canonicalization Scheme. URL: https://www.rfc-editor.org/rfc/rfc8785 38 | * - [RFC9110] 39 | - HTTP Semantics. June 2022. URL: https://www.rfc-editor.org/rfc/rfc9110 40 | * - [RFC9457] 41 | - Problem Details for HTTP APIs. URL: https://www.rfc-editor.org/rfc/rfc9457.html 42 | * - [RFC9535] 43 | - JSONPath: Query Expressions for JSON. URL: https://www.rfc-editor.org/rfc/rfc9535 44 | * - [ISO8601] 45 | - ISO/TC 154, Date and time - Representations for information interchange, URL: https://www.iso.org/standard/70907.html 46 | * - [JPEG/ISO10918-1] 47 | - ISO/IEC JTC 1/SC 29, Information technology - Digital compression and coding of continuous-tone still images, URL: https://www.iso.org/standard/18902.html 48 | * - [JP2000/ISO15444-1] 49 | - ISO/IEC JTC 1/SC 29 , Information technology - JPEG 2000 image coding system - Part 1: Core coding system, URL: https://www.iso.org/standard/78321.html 50 | * - [PNG/ISO15948] 51 | - ISO/IEC JTC 1/SC 24, Information technology - Computer graphics and image processing - Portable Network Graphics (PNG): Functional specification, URL: https://www.iso.org/standard/29581.html 52 | * - [ISO19794] 53 | - ISO/IEC JTC 1/SC 37, Information technology — Biometric data interchange formats, URL: https://www.iso.org/standard/50866.html 54 | * - [json/ISO21778] 55 | - ISO/IEC JTC 1/SC 22, Information technology - The JSON data interchange syntax, URL: https://www.iso.org/standard/71616.html 56 | * - [NFIQ/ISO29794-4] 57 | - ISO/IEC JTC 1/SC 37, Information technology - Biometric sample quality - Part 4: Finger image data, URL: https://www.iso.org/standard/83827.html 58 | * - [ISO30108-1] 59 | - ISO/IEC JTC 1/SC 37, Information technology - Biometric Identity Assurance Services - Part 1: BIAS services, URL: https://www.iso.org/standard/53228.html 60 | * - [PDF/ISO32000] 61 | - ISO/TC 171/SC 2, Document management - Portable document format - Part 2: PDF 2.0, URL: https://www.iso.org/standard/75839.html 62 | * - [ISO/IEC 19794] 63 | - ISO/IEC JTC 1/SC 37, Information technology - Biometric data interchange formats, 64 | * - [ISO/IEC 39794] 65 | - ISO/IEC JTC 1/SC 37, Information technology - Biometric data interchange formats, 66 | -------------------------------------------------------------------------------- /src/doc/images/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 19 | 21 | 24 | 28 | 29 | 30 | 52 | 54 | 55 | 57 | image/svg+xml 58 | 60 | 61 | 62 | 63 | 64 | 69 | 72 | 77 | 78 | 81 | 84 | 87 | 92 | 93 | 96 | 101 | 102 | 107 | 110 | 115 | 116 | 117 | 118 | 119 | 120 | -------------------------------------------------------------------------------- /src/doc/functional/_notification.rst: -------------------------------------------------------------------------------- 1 | 2 | Notification 3 | ------------ 4 | 5 | See :ref:`annex-interface-notification` for the technical details of this interface. 6 | 7 | The subscription & notification process is managed by a middleware and is described 8 | in the following diagram: 9 | 10 | .. uml:: 11 | :caption: Subscription & Notification Process 12 | :scale: 50% 13 | 14 | hide footbox 15 | participant "Emitter" as PR 16 | participant "Notification\nEngine" as N 17 | participant "Subscriber" as CR 18 | 19 | note over PR,N: First step is to create the topic 20 | PR -> N: create_topic(name) 21 | activate PR 22 | activate N 23 | N --> PR: uuid 24 | deactivate N 25 | deactivate PR 26 | 27 | note over N,CR: Then a system can subscribe for events published on that topic 28 | 29 | CR -> N: subscribe(topic,notify_URL) 30 | activate CR 31 | activate N 32 | N --> CR: id 33 | deactivate CR 34 | deactivate N 35 | 36 | ... later ... 37 | 38 | note over N,CR: confirm the address before the subscription is active 39 | 40 | N -> CR: notify(message) 41 | activate N 42 | activate CR 43 | CR -> N: confirm(token) 44 | activate N #FFBBBB 45 | N --> CR: ok 46 | deactivate N 47 | CR --> N: ok 48 | deactivate CR 49 | deactivate N 50 | 51 | note over PR,CR: it is now possible to publish notification 52 | 53 | PR -> N: publish(message) 54 | activate PR 55 | activate N 56 | N -> N: store 57 | N --> PR: ok 58 | deactivate PR 59 | 60 | ... 61 | 62 | loop subscriptions 63 | N -> CR: notify(message) 64 | activate CR 65 | CR --> N: ok 66 | deactivate CR 67 | end 68 | deactivate N 69 | 70 | 71 | 72 | Services 73 | """""""" 74 | 75 | For the Subscriber 76 | '''''''''''''''''' 77 | 78 | .. py:function:: subscribe(topic,URL) 79 | :noindex: 80 | 81 | Subscribe a URL to receive notifications sent to one topic 82 | 83 | **Authorization**: ``notif.sub.write`` 84 | 85 | :param str topic: Topic 86 | :param str URL: URL to be called when a notification is available 87 | :return: a subscription ID 88 | 89 | This service is synchronous. 90 | 91 | .. py:function:: listSubscriptions() 92 | :noindex: 93 | 94 | Get all subscriptions 95 | 96 | **Authorization**: ``notif.sub.read`` 97 | 98 | :param str URL: URL to be called when a notification is available 99 | :return: a subscription ID 100 | 101 | This service is synchronous. 102 | 103 | .. py:function:: unsubscribe(id) 104 | :noindex: 105 | 106 | Unsubscribe a URL from the list of receiver for one topic 107 | 108 | **Authorization**: ``notif.sub.write`` 109 | 110 | :param str id: Subscription ID 111 | :return: bool 112 | 113 | This service is synchronous. 114 | 115 | .. py:function:: confirm(token) 116 | :noindex: 117 | 118 | Used to confirm that the URL used during the subscription is valid 119 | 120 | **Authorization**: ``notif.sub.write`` 121 | 122 | :param str token: A token send through the URL. 123 | :return: bool 124 | 125 | This service is synchronous. 126 | 127 | For the Publisher 128 | ''''''''''''''''' 129 | 130 | .. py:function:: createTopic(topic) 131 | :noindex: 132 | 133 | Create a new topic. This is required before an event can be sent to it. 134 | 135 | **Authorization**: ``notif.topic.write`` 136 | 137 | :param str topic: Topic 138 | :return: N/A 139 | 140 | This service is synchronous. 141 | 142 | .. py:function:: listTopics() 143 | :noindex: 144 | 145 | Get the list of all existing topics. 146 | 147 | **Authorization**: ``notif.topic.read`` 148 | 149 | :return: N/A 150 | 151 | This service is synchronous. 152 | 153 | .. py:function:: deleteTopic(topic) 154 | :noindex: 155 | 156 | Delete a topic. 157 | 158 | **Authorization**: ``notif.topic.write`` 159 | 160 | :param str topic: Topic 161 | :return: N/A 162 | 163 | This service is synchronous. 164 | 165 | .. py:function:: publish(topic,subject,message) 166 | :noindex: 167 | 168 | Notify of a new event all systems that subscribed to this topic 169 | 170 | **Authorization**: ``notif.topic.publish`` 171 | 172 | :param str topic: Topic 173 | :param str subject: The subject of the message 174 | :param str message: The message itself (a string buffer) 175 | :return: N/A 176 | 177 | This service is asynchronous (systems that subscribed on this topic are notified asynchronously). 178 | 179 | For the Receiver 180 | '''''''''''''''' 181 | 182 | .. py:function:: notify(message) 183 | :noindex: 184 | 185 | Receive an event published by a publisher. 186 | This service needs to be registered through the subscription process. 187 | 188 | :param str message: The message itself (a string buffer) 189 | :return: N/A 190 | 191 | Dictionaries 192 | """""""""""" 193 | 194 | As an example, below there is a list of events that each component might handle. 195 | 196 | .. list-table:: Event Type 197 | :header-rows: 1 198 | 199 | * - Event Type 200 | - Emitted by CR 201 | - Emitted by PR 202 | 203 | * - Live birth 204 | - |tick| 205 | - 206 | * - Death 207 | - |tick| 208 | - 209 | * - Fœtal Death 210 | - |tick| 211 | - 212 | * - Marriage 213 | - |tick| 214 | - 215 | * - Divorce 216 | - |tick| 217 | - 218 | * - Annulment 219 | - |tick| 220 | - 221 | * - Separation, judicial 222 | - |tick| 223 | - 224 | * - Adoption 225 | - |tick| 226 | - 227 | * - Legitimation 228 | - |tick| 229 | - 230 | * - Recognition 231 | - |tick| 232 | - 233 | * - Change of name 234 | - |tick| 235 | - 236 | * - Change of gender 237 | - |tick| 238 | - 239 | * - New person 240 | - 241 | - |tick| 242 | * - Duplicate person 243 | - |tick| 244 | - |tick| 245 | -------------------------------------------------------------------------------- /src/doc/functional/_3rdparty.rst: -------------------------------------------------------------------------------- 1 | 2 | Third Party Services 3 | -------------------- 4 | 5 | Third Party Services consist of a set of services implemented on top of identity systems to favour third parties 6 | consumption of identity data. The services can be classified in two sets: 7 | 8 | - Submitting citizen ID attributes for validation 9 | 10 | The purpose is to extend the use of government-issued identity to registered 11 | third party services. The individual will submit their ID attributes to the third party in order to enroll 12 | for, or access, a particular service. The third party will leverage the API to access the identity 13 | management system and verify the individual's identity. In this way, external third parties can quickly and 14 | easily verify individuals based on their government issued ID attributes. 15 | 16 | .. admonition:: Use case applications: telco enrollment 17 | 18 | The API enables a telco operator to check an individual's identity when he is applying for a service contract. 19 | The telco relies on the government to confirm that the attributes submitted by the individual match against 20 | the data held in the database therefore being able to confidently identify the new subscriber. This scenario 21 | can be replicated across multiple sectors including banking and finance. 22 | 23 | - User-initiated attributes sharing 24 | 25 | The purpose is to enable the user to share their attributes with a chosen third party using 26 | well-known internet protocol: OpenID Connect. The third party benefits from the government's verified attributes. 27 | 28 | .. admonition:: Use case applications: on-line registration to gambling website 29 | 30 | The API enables individuals to log-in with their government credential (log-in/password) and share 31 | verified attributes ex. age (above 18) with the third party. 32 | 33 | Services 34 | """""""" 35 | 36 | .. py:function:: verifyIdentity(Identifier, attributeSet) 37 | :noindex: 38 | 39 | Verify an Identity based on an identifier (UIN, token…) and a set of Identity Attributes. Verification is strictly 40 | matching all provided identity attributes to compute the global Boolean matching result. 41 | 42 | **Authorization**: `id.verify` 43 | 44 | :param str Identifier: The person's Identifier 45 | :param list[str] attributeSet: A set of identity attributes associated to the identifier and to be verified by the system 46 | :return: Y or N 47 | 48 | In case of error (unknown attributes, unauthorized access, etc.) the value is replaced with an error 49 | 50 | .. py:function:: identify(attributeSet, outputAttributeSet) 51 | :noindex: 52 | 53 | Identify possibly matching identities against an input set of attributes. Returns an array of predefined 54 | datasets as described by outputAttributeSet. 55 | 56 | Note: This service may be limited to some specific government RPs 57 | 58 | **Authorization**: `id.identify` 59 | 60 | :param list[str] attributeSet: A list of pair (name,value) requested 61 | :param list[str] outputAttributeSet: An array of attributes requested 62 | :return: Y or N 63 | 64 | In case of error (unknown attributes, unauthorized access, etc.) the value is replaced with an error 65 | 66 | .. py:function:: readAttributes(Identifier, outputAttributeSet) 67 | :noindex: 68 | 69 | Get a list of identity attributes attached to a given identifier. 70 | 71 | **Authorization**: `id.read` 72 | 73 | :param str Identifier: The person's Identifier 74 | :param list[str] outputAttributeSet: defining the identity attributes to be provided back to the caller 75 | :return: An array of the requested attributes 76 | 77 | In case of error (unknown attributes, unauthorized access, etc.) the value is replaced with an error 78 | 79 | .. py:function:: readAttributeSet(Identifier, AttributeSetName) 80 | :noindex: 81 | 82 | Get a set of identity attributes as defined by attributeSet, attached to a given identifier. 83 | 84 | **Authorization**: `id.set.read` 85 | 86 | :param str Identifier: The person's Identifier 87 | :param str attributeSetName: The name of predefined attributes set name 88 | :return: An array of the requested attributes 89 | 90 | In case of error (unknown attributes, unauthorized access, etc.) the value is replaced with an error 91 | 92 | Attribute set 93 | """"""""""""" 94 | 95 | When identity attributes are exchanged, they are included in an attribute set, possibly containing groups like 96 | biographic data, biometric data, document data, contact data... This structure is extensible and may be complemented 97 | with other data groups, and each group may contain any number of attribute name / attribute value pairs. 98 | 99 | Attribute set name 100 | """""""""""""""""" 101 | 102 | Attribute sets are by definition structures with variable and optional content, hence it may be useful to pre-agree 103 | on a given attribute set content and name between two or more systems in a given project scope. 104 | 105 | Any string may be used to define an attribute set name, but in the scope of this specification following names are 106 | reserved and predefined: 107 | 108 | .. list-table:: 109 | :header-rows: 1 110 | 111 | * - Name 112 | - Description 113 | - Data Included 114 | * - "DEFAULT_SET_01" 115 | - Minimum demographic data 116 | - - First name 117 | - Last name 118 | - DoB 119 | - Place of birth 120 | * - "DEFAULT_SET_02" 121 | - Minimum demographic and portrait 122 | - Minimum demographic data + portrait 123 | * - "DEFAULT_SET_EIDAS" 124 | - Set expected to comply with eIDAS pivotal attributes [#]_. 125 | - Mandatory attributes: 126 | 127 | - First name 128 | - Last name 129 | - DoB 130 | - Identifier 131 | 132 | Optional attributes: 133 | 134 | - Birth name 135 | - Place of birth 136 | - Gender 137 | - Current address 138 | 139 | 140 | 141 | Output Attribute set 142 | """""""""""""""""""" 143 | 144 | To specify what identity attributes are expected in return when performing e.g. an identify request or a read attributes. 145 | 146 | 147 | .. [#] `eIDAS SAML Attribute Profile `_ 148 | 149 | -------------------------------------------------------------------------------- /src/doc/conf.py: -------------------------------------------------------------------------------- 1 | 2 | # (c) Secure Identity Alliance 3 | 4 | import datetime 5 | 6 | source_suffix = {'.rst': 'restructuredtext'} 7 | master_doc = 'index' 8 | exclude_patterns = [] 9 | pygments_style = 'colorful' 10 | project = 'OSIA' 11 | release = '7.0-DRAFT' 12 | author = 'SIA' 13 | 14 | numfig = True 15 | 16 | extensions = ['sphinxcontrib.httpdomain','sphinxcontrib.plantuml','sphinxcontrib.openapi'] 17 | 18 | plantuml_output_format = 'svg' 19 | 20 | exclude_patterns = ['_*.rst', '*/_*.rst'] 21 | 22 | rst_prolog = ''' 23 | 24 | .. meta:: 25 | :http-equiv=X-UA-Compatible: IE=9 26 | 27 | .. |tick| unicode:: U+2714 .. HEAVY CHECK MARK 28 | .. |project| replace:: OSIA 29 | .. |release| replace:: '''+release+''' 30 | 31 | .. role:: todo 32 | 33 | .. raw:: html 34 | 35 | 68 | 69 | ''' 70 | 71 | # 72 | # HTML Output Configuration 73 | # 74 | html_static_path = ['images'] 75 | html_theme = "alabaster" 76 | html_theme_options = { 77 | 'logo': 'logo.svg', 78 | 'github_user': 'SecureIdentityAlliance', 79 | 'github_repo': 'osia', 80 | 'github_button': True, 81 | 'show_powered_by': False, 82 | 'show_relbars': True, 83 | 'fixed_sidebar': False, 84 | } 85 | html_show_sourcelink = False 86 | html_context = {'project':'OSIA', 'version':release, 'copyright':'Secure Identity Alliance, '+str(datetime.date.today().year)} 87 | html_last_updated_fmt = '%b %d, %Y' 88 | html_extra_path = ['yaml'] 89 | 90 | # 91 | # Latex/PDF Output Configuration 92 | # 93 | 94 | # use small font for source code 95 | # XXX investigate if it is possible to customize \sphinxVerbatim environment 96 | from sphinx.highlighting import PygmentsBridge 97 | from pygments.formatters.latex import LatexFormatter 98 | 99 | class CustomLatexFormatter(LatexFormatter): 100 | def __init__(self, **options): 101 | super(CustomLatexFormatter, self).__init__(**options) 102 | self.verboptions = r"formatcom=\footnotesize" 103 | 104 | PygmentsBridge.latex_formatter = CustomLatexFormatter 105 | 106 | latex_elements = { 107 | # The paper size ('letterpaper' or 'a4paper'). 108 | 'papersize': 'a4paper', 109 | 110 | # The font size ('10pt', '11pt' or '12pt'). 111 | 'pointsize': '10pt', 112 | 113 | # Keep the figure where there are defined (no floating) 114 | 'figure_align':'H', 115 | 116 | # no raw string can contain '\u' (this is interpreted as unicode char) 117 | 'preamble': u''' 118 | \\usepackage{bbding,pifont} %% two dingbat fonts 119 | \\usepackage{attachfile} 120 | 121 | \\attachfilesetup{author=Secure Identity Alliance,color=0 0.5 0.5} 122 | 123 | \\DeclareUnicodeCharacter{2714}{\\Checkmark} 124 | \\newcommand{\\DUroletodo}[1]{\\colorbox{yellow}{#1} } 125 | \\usepackage{color} 126 | \\usepackage{colortbl} 127 | \\definecolor{tableheader}{rgb}{0.678,0.325,0.537} 128 | 129 | \\usepackage{makeidx} 130 | \\usepackage[columns=1]{idxlayout} 131 | 132 | \\usepackage{draftwatermark} 133 | \\SetWatermarkScale{0.5} 134 | 135 | ''' + r''' 136 | 137 | \renewcommand*{\sphinxstyletheadfamily}{\cellcolor{tableheader}\sffamily\color{white}} 138 | 139 | \newcommand{\companylogo}{ 140 | \includegraphics [ width=3.5cm] {logo.pdf} 141 | } 142 | \newcommand{\companylogobig}{ 143 | \includegraphics [ width=10cm] {logo2.pdf} 144 | } 145 | 146 | %% HEADER-FOOTER 147 | %%\fancypagestyle{plain}{ 148 | %% \fancyhead[L]{ \companylogo } 149 | %%} 150 | %%\fancypagestyle{normal}{ 151 | %% \fancyhead[L]{ \companylogo } 152 | %%} 153 | 154 | %% TITLE 155 | \newcommand{\osiamaketitle}{ 156 | \begin{titlepage} 157 | \let\footnotesize\small 158 | \let\footnoterule\relax 159 | \begin{center} 160 | {\vspace{0.5cm} \companylogo } 161 | \vspace{1.5cm} 162 | \par 163 | {\rm\Huge\sffamily\bfseries {\textcolor[rgb]{0.678,0.325,0.537}{Specifications version '''+release+r'''} } \par} 164 | \vfill 165 | %% Project logo 166 | \includegraphics[ width=12cm]{logo2.pdf} \par 167 | \vfill 168 | \small {\textcolor[rgb]{0.678,0.325,0.537}{\textcopyright Secure Identity Alliance, '''+str(datetime.date.today().year)+r''' } } 169 | \end{center} 170 | 171 | \par 172 | \end{titlepage} 173 | \cleardoublepage 174 | \setcounter{footnote}{0} 175 | \relax\let\maketitle\relax 176 | } 177 | 178 | ''', 179 | 180 | 'maketitle': r'\osiamaketitle', 181 | 'atendofbody':u''' 182 | \\listoftables 183 | \\listoffigures 184 | ''', 185 | 186 | 'classoptions' : ',english,openany,oneside' 187 | } 188 | 189 | if 'DRAFT' in release: 190 | latex_elements['preamble'] += '\\SetWatermarkText{DRAFT}' 191 | rst_prolog += ''' 192 | .. raw:: html 193 | 194 | 200 | ''' 201 | else: 202 | latex_elements['preamble'] += '\\SetWatermarkText{}' 203 | 204 | 205 | # Copy images 206 | import os,shutil,fnmatch 207 | def setup(app): 208 | try: 209 | os.makedirs(app.outdir) 210 | except: 211 | pass 212 | for root, dirs, files in os.walk(os.path.join(app.srcdir,'images')): 213 | for f in fnmatch.filter(files,"*.pdf"): 214 | shutil.copy(os.path.join(root,f),app.outdir) 215 | 216 | 217 | if 'itu' in tags: 218 | rst_prolog += ''' 219 | .. |osia| replace:: ITU-T X.1281 220 | .. |specification| replace:: recommendation 221 | .. |chapter| replace:: clause 222 | ''' 223 | else: 224 | rst_prolog += ''' 225 | .. |osia| replace:: OSIA 226 | .. |specification| replace:: specification 227 | .. |chapter| replace:: chapter 228 | ''' 229 | -------------------------------------------------------------------------------- /src/doc/technical/notification.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _annex-interface-notification: 3 | 4 | Notification 5 | ------------ 6 | 7 | This is version :openapi:version:`../yaml/notification.yaml` of this interface. 8 | 9 | .. only:: html 10 | 11 | Get the OpenAPI file: `notification.yaml <../notification.yaml>`_ 12 | 13 | .. raw:: latex 14 | 15 | Get the OpenAPI file: \textattachfile[]{../html/notification.yaml}{notification.yaml} 16 | 17 | .. sidebar:: Notification Services 18 | 19 | .. openapi:toc:: ../yaml/notification.yaml 20 | :nb_columns: 1 21 | 22 | Services 23 | """""""" 24 | .. openapi:: ../yaml/notification.yaml 25 | :examples: 26 | :group: 27 | :group_examples: 28 | 29 | Receiver 30 | '''''''' 31 | .. _notify_URL: 32 | 33 | .. http:post:: notify_URL 34 | :synopsis: Notify service receiving the events 35 | 36 | :reqheader message-type: the type of the message (Required) 37 | :reqheader subscription-id: the unique ID of the subscription 38 | :reqheader message-id: the unique ID of the message (Required) 39 | :reqheader topic-id: the unique ID of the topic (Required) 40 | :status 200: Message received and processed. 41 | :status 500: Unexpected error 42 | 43 | **Example request (Subscription Confirmation):** 44 | 45 | .. sourcecode:: http 46 | 47 | POST notify_URL HTTP/1.1 48 | Host: example.com 49 | Content-Type: application/json 50 | Message-Type: SubscriptionConfirmation 51 | Subscription-Id: XXX 52 | Message-Id: YYY 53 | Topic-ID: ZZZ 54 | 55 | { 56 | "type": "SubscriptionConfirmation", 57 | "token": "string", 58 | "topic": "string", 59 | "message": "string", 60 | "messageId": "string", 61 | "subject": "string", 62 | "confirmURL": "https://example.com", 63 | "timestamp": "string" 64 | } 65 | 66 | **Example request (Event):** 67 | 68 | .. sourcecode:: http 69 | 70 | POST notify_URL HTTP/1.1 71 | Host: example.com 72 | Content-Type: application/json 73 | Message-Type: Notification 74 | Message-Id: YYY 75 | Topic-ID: ZZZ 76 | 77 | {"key": "data"} 78 | 79 | **Example response:** 80 | 81 | .. sourcecode:: http 82 | 83 | HTTP/1.1 500 Internal Server Error 84 | Content-Type: application/json 85 | 86 | { 87 | "code": 1, 88 | "message": "string" 89 | } 90 | 91 | 92 | Notification Message 93 | """""""""""""""""""" 94 | 95 | This section describes the messages exchanged through notification. All messages 96 | are encoded in ``json``. They are generated by the emitter (the source of the event) 97 | and received by zero, one, or many receivers that have subscribed to the type of event. 98 | 99 | .. list-table:: Event Type & Message 100 | :header-rows: 1 101 | :widths: 30 70 102 | :class: longtable 103 | 104 | * - Event Type 105 | - Message 106 | 107 | * - ``liveBirth`` 108 | - - ``source``: identification of the system emitting the event 109 | - ``uin`` of the new born 110 | - ``uin1`` of the first parent (optional if parent is unknown) 111 | - ``uin2`` of the second parent (optional if parent is unknown) 112 | 113 | Example: 114 | 115 | .. code-block:: json 116 | 117 | { 118 | "source": "systemX", 119 | "uin": "123456789", 120 | "uin1": "123456789", 121 | "uin2": "234567890" 122 | } 123 | 124 | * - ``death`` 125 | - - ``source``: identification of the system emitting the event 126 | - ``uin`` of the dead person 127 | 128 | Example: 129 | 130 | .. code-block:: json 131 | 132 | { 133 | "source": "systemX", 134 | "uin": "123456789" 135 | } 136 | 137 | * - ``birthCancellation`` 138 | - - ``source``: identification of the system emitting the event 139 | - ``uin`` of the person whose birth declaration is being cancelled 140 | 141 | Example: 142 | 143 | .. code-block:: json 144 | 145 | { 146 | "source": "systemX", 147 | "uin": "123456789", 148 | } 149 | 150 | * - ``foetalDeath`` 151 | - - ``source``: identification of the system emitting the event 152 | - ``uin`` of the new born 153 | 154 | Example: 155 | 156 | .. code-block:: json 157 | 158 | { 159 | "source": "systemX", 160 | "uin": "123456789" 161 | } 162 | 163 | * - ``marriage`` 164 | - - ``source``: identification of the system emitting the event 165 | - ``uin1`` of the first conjoint 166 | - ``uin2`` of the second conjoint 167 | 168 | Example: 169 | 170 | .. code-block:: json 171 | 172 | { 173 | "source": "systemX", 174 | "uin1": "123456789", 175 | "uin2": "234567890" 176 | } 177 | 178 | * - ``divorce`` 179 | - - ``source``: identification of the system emitting the event 180 | - ``uin1`` of the first conjoint 181 | - ``uin2`` of the second conjoint 182 | 183 | Example: 184 | 185 | .. code-block:: json 186 | 187 | { 188 | "source": "systemX", 189 | "uin1": "123456789", 190 | "uin2": "234567890" 191 | } 192 | 193 | * - ``annulment`` 194 | - - ``source``: identification of the system emitting the event 195 | - ``uin1`` of the first conjoint 196 | - ``uin2`` of the second conjoint 197 | 198 | Example: 199 | 200 | .. code-block:: json 201 | 202 | { 203 | "source": "systemX", 204 | "uin1": "123456789", 205 | "uin2": "234567890" 206 | } 207 | 208 | * - ``separation`` 209 | - - ``source``: identification of the system emitting the event 210 | - ``uin1`` of the first conjoint 211 | - ``uin2`` of the second conjoint 212 | 213 | Example: 214 | 215 | .. code-block:: json 216 | 217 | { 218 | "source": "systemX", 219 | "uin1": "123456789", 220 | "uin2": "234567890" 221 | } 222 | 223 | * - ``adoption`` 224 | - - ``source``: identification of the system emitting the event 225 | - ``uin`` of the child 226 | - ``uin1`` of the first parent 227 | - ``uin2`` of the second parent (optional) 228 | 229 | Example: 230 | 231 | .. code-block:: json 232 | 233 | { 234 | "source": "systemX", 235 | "uin": "123456789", 236 | "uin1": "234567890" 237 | } 238 | 239 | * - ``legitimation`` 240 | - - ``source``: identification of the system emitting the event 241 | - ``uin`` of the child 242 | - ``uin1`` of the first parent 243 | - ``uin2`` of the second parent (optional) 244 | 245 | Example: 246 | 247 | .. code-block:: json 248 | 249 | { 250 | "source": "systemX", 251 | "uin": "987654321", 252 | "uin1": "123456789", 253 | "uin2": "234567890" 254 | } 255 | 256 | * - ``recognition`` 257 | - - ``source``: identification of the system emitting the event 258 | - ``uin`` of the child 259 | - ``uin1`` of the first parent 260 | - ``uin2`` of the second parent (optional) 261 | 262 | Example: 263 | 264 | .. code-block:: json 265 | 266 | { 267 | "source": "systemX", 268 | "uin": "123456789", 269 | "uin2": "234567890" 270 | } 271 | 272 | * - ``changeOfName`` 273 | - - ``source``: identification of the system emitting the event 274 | - ``uin`` of the person 275 | 276 | Example: 277 | 278 | .. code-block:: json 279 | 280 | { 281 | "source": "systemX", 282 | "uin": "123456789" 283 | } 284 | 285 | * - ``changeOfGender`` 286 | - - ``source``: identification of the system emitting the event 287 | - ``uin`` of the person 288 | 289 | Example: 290 | 291 | .. code-block:: json 292 | 293 | { 294 | "source": "systemX", 295 | "uin": "123456789" 296 | } 297 | 298 | * - ``updatePerson`` 299 | - - ``source``: identification of the system emitting the event 300 | - ``uin`` of the person 301 | 302 | Example: 303 | 304 | .. code-block:: json 305 | 306 | { 307 | "source": "systemX", 308 | "uin": "123456789" 309 | } 310 | 311 | * - ``newPerson`` 312 | - - ``source``: identification of the system emitting the event 313 | - ``uin`` of the person 314 | 315 | Example: 316 | 317 | .. code-block:: json 318 | 319 | { 320 | "source": "systemX", 321 | "uin": "123456789" 322 | } 323 | 324 | * - ``duplicatePerson`` 325 | - - ``source``: identification of the system emitting the event 326 | - ``uin`` of the person to be kept 327 | - ``duplicates``: list of uin for records identified as duplicates 328 | 329 | Example: 330 | 331 | .. code-block:: json 332 | 333 | { 334 | "source": "systemX", 335 | "uin": "123456789", 336 | "duplicates": [ 337 | "234567890", 338 | "345678901" 339 | ] 340 | } 341 | 342 | .. note:: 343 | 344 | Anonymized notification of events will be treated separately. 345 | 346 | 347 | -------------------------------------------------------------------------------- /src/doc/functional/_dataaccess.rst: -------------------------------------------------------------------------------- 1 | 2 | Data Access 3 | ----------- 4 | 5 | See :ref:`annex-interface-dataaccess` for the technical details of this interface. 6 | 7 | Services 8 | """""""" 9 | 10 | .. py:function:: readPersonAttributes(UIN, names) 11 | :noindex: 12 | 13 | Read person attributes. 14 | 15 | **Authorization**: ``pr.person.read`` or ``cr.person.read`` 16 | 17 | :param str UIN: The person's UIN 18 | :param list[str] names: The names of the attributes requested 19 | :return: a list of pair (name,value). In case of error (unknown attributes, unauthorized access, etc.) the value is replaced with an error 20 | 21 | This service is synchronous. It can be used to retrieve attributes from CR or from PR. 22 | 23 | .. uml:: 24 | :caption: ``readPersonAttributes`` Sequence Diagram 25 | :scale: 50% 26 | 27 | hide footbox 28 | participant "CR" as CR 29 | participant "PR" as PR 30 | 31 | note over CR,PR: CR can request person's attributes from PR 32 | CR -> PR: readPersonAttributes(UIN,[names]) 33 | PR -->> CR: attributes 34 | 35 | note over CR,PR: PR can request person's attributes from CR 36 | PR -> CR: readPersonAttributes(UIN,[names]) 37 | CR -->> PR: attributes 38 | 39 | ------- 40 | 41 | .. py:function:: matchPersonAttributes(UIN, attributes) 42 | :noindex: 43 | 44 | Match person attributes. This service is used to check the value of attributes without exposing private data. 45 | The implementation can use a simple comparison or a more advanced technique (for example: phonetic comparison for names) 46 | 47 | **Authorization**: ``pr.person.match`` or ``cr.person.match`` 48 | 49 | :param str UIN: The person's UIN 50 | :param list[(str,str)] attributes: The attributes to match. Each attribute is described with its name and the expected value 51 | :return: If all attributes match, a *Yes* is returned. If one attribute does not match, a *No* is returned along with a list of (name,reason) for each non-matching attribute. 52 | 53 | This service is synchronous. It can be used to match attributes in CR or in PR. 54 | 55 | .. uml:: 56 | :caption: ``matchPersonAttributes`` Sequence Diagram 57 | :scale: 50% 58 | 59 | hide footbox 60 | participant "CR" as CR 61 | participant "PR" as PR 62 | 63 | note over CR,PR: CR can match person's attributes in PR 64 | CR -> PR: matchPersonAttributes(UIN,[attributes]) 65 | PR -->> CR: Y/N+reasons 66 | 67 | note over CR,PR: PR can match person's attributes in CR 68 | PR -> CR: matchPersonAttributes(UIN,[attributes]) 69 | CR -->> PR: Y/N+reasons 70 | 71 | ------- 72 | 73 | .. py:function:: verifyPersonAttributes(UIN, expressions) 74 | :noindex: 75 | 76 | Evaluate expressions on person attributes. This service is used to evaluate simple expressions on person's attributes 77 | without exposing private data 78 | The implementation can use a simple comparison or a more advanced technique (for example: phonetic comparison for names) 79 | 80 | **Authorization**: ``pr.person.verify`` or ``cr.person.verify`` 81 | 82 | :param str UIN: The person's UIN 83 | :param list[(str,str,str)] expressions: The expressions to evaluate. Each expression is described with the attribute's name, the operator (one of ``<``, ``>``, ``=``, ``>=``, ``<=``) and the attribute value 84 | :return: A *Yes* if all expressions are true, a *No* if one expression is false. 85 | 86 | This service is synchronous. It can be used to verify attributes in CR or in PR. 87 | 88 | .. uml:: 89 | :caption: ``verifyPersonAttributes`` Sequence Diagram 90 | :scale: 50% 91 | 92 | hide footbox 93 | participant "CR" as CR 94 | participant "PR" as PR 95 | 96 | note over CR,PR: CR can verify person's attributes in PR 97 | CR -> PR: verifyPersonAttributes(UIN,[expressions]) 98 | PR -->> CR: Y/N/U 99 | 100 | note over CR,PR: PR can verify person's attributes in CR 101 | PR -> CR: verifyPersonAttributes(UIN,[expressions]) 102 | CR -->> PR: Y/N/U 103 | 104 | ------- 105 | 106 | .. py:function:: queryPersonUIN(attributes, offset, limit) 107 | :noindex: 108 | 109 | Query the persons by a set of attributes. This service is used when the UIN is unknown. 110 | The implementation can use a simple comparison or a more advanced technique (for example: phonetic comparison for names) 111 | 112 | **Authorization**: ``pr.person.read`` or ``cr.person.read`` 113 | 114 | :param list[(str,str)] attributes: The attributes to be used to find UIN. Each attribute is described with its name and its value 115 | :param int offset: The offset of the query (first item of the response) (optional, default to ``0``) 116 | :param int limit: The maximum number of items to return (optional, default to ``100``) 117 | :return: a list of matching UIN 118 | 119 | This service is synchronous. It can be used to get the UIN of a person. 120 | 121 | .. uml:: 122 | :caption: ``queryPersonUIN`` Sequence Diagram 123 | :scale: 50% 124 | 125 | hide footbox 126 | participant "CR" as CR 127 | participant "PR" as PR 128 | 129 | note over CR,PR: CR can get UIN from PR 130 | CR -> PR: queryPersonUIN([attributes]) 131 | PR -->> CR: [UIN] 132 | 133 | note over CR,PR: PR can get UIN from CR 134 | PR -> CR: queryPersonUIN([attributes]) 135 | CR -->> PR: [UIN] 136 | 137 | ------- 138 | 139 | .. py:function:: queryPersonList(attributes, names, offset, limit) 140 | :noindex: 141 | 142 | Query the persons by a list of attributes and their values. 143 | This service is proposed as an optimization of a sequence of calls to 144 | :py:func:`queryPersonUIN` and :py:func:`readPersonAttributes`. 145 | 146 | **Authorization**: ``pr.person.read`` or ``cr.person.read`` 147 | 148 | :param list[(str,str)] attributes: The attributes to be used to find the persons. Each attribute is described with its name and its value 149 | :param list[str] names: The names of the attributes requested 150 | :param int offset: The offset of the query (first item of the response) (optional, default to ``0``) 151 | :param int limit: The maximum number of items to return (optional, default to ``100``) 152 | :return: a list of lists of pairs (name,value). In case of error (unknown attributes, unauthorized access, etc.) the value is replaced with an error 153 | 154 | This service is synchronous. It can be used to retrieve attributes from CR or from PR. 155 | 156 | .. uml:: 157 | :caption: ``queryPersonList`` Sequence Diagram 158 | :scale: 50% 159 | 160 | hide footbox 161 | participant "CR" as CR 162 | participant "PR" as PR 163 | 164 | note over CR,PR: CR can request person's attributes from PR 165 | CR -> PR: queryPersonList([attributes],[names]) 166 | PR -->> CR: [attributes] 167 | 168 | note over CR,PR: PR can request person's attributes from CR 169 | PR -> CR: queryPersonList([attributes],[names]) 170 | CR -->> PR: [attributes] 171 | 172 | ------- 173 | 174 | .. py:function:: readDocument(UINs,documentType,format) 175 | :noindex: 176 | 177 | Read in a selected format (PDF, image, ...) a document such as a marriage certificate. 178 | 179 | **Authorization**: ``pr.document.read`` or ``cr.document.read`` 180 | 181 | :param list[str] UIN: The list of UINs for the persons concerned by the document 182 | :param str documentType: The type of document (birth certificate, etc.) 183 | :param str format: The format of the returned/requested document 184 | :return: The list of the requested documents 185 | 186 | This service is synchronous. It can be used to get the documents for a person. 187 | 188 | .. uml:: 189 | :caption: ``readDocument`` Sequence Diagram 190 | :scale: 50% 191 | 192 | hide footbox 193 | participant "CR" as CR 194 | participant "PR" as PR 195 | 196 | note over CR,PR: CR can get a document from PR 197 | CR -> PR: readDocument([UIN],documentType,format) 198 | PR -->> CR: [documents] 199 | 200 | note over CR,PR: PR can get a document from CR 201 | PR -> CR: readDocument([UIN],documentType,format) 202 | CR -->> PR: [documents] 203 | 204 | Dictionaries 205 | """""""""""" 206 | 207 | As an example, below there is a list of attributes/documents that each component might handle. 208 | 209 | .. list-table:: Person Attributes 210 | :header-rows: 1 211 | 212 | * - Attribute Name 213 | - In CR 214 | - In PR 215 | 216 | * - UIN 217 | - |tick| 218 | - |tick| 219 | * - first name 220 | - |tick| 221 | - |tick| 222 | * - last name 223 | - |tick| 224 | - |tick| 225 | * - spouse name 226 | - |tick| 227 | - |tick| 228 | * - date of birth 229 | - |tick| 230 | - |tick| 231 | * - place of birth 232 | - |tick| 233 | - |tick| 234 | * - gender 235 | - |tick| 236 | - |tick| 237 | * - date of death 238 | - |tick| 239 | - |tick| 240 | * - place of death 241 | - |tick| 242 | - 243 | * - reason of death 244 | - |tick| 245 | - 246 | * - status 247 | - 248 | - |tick| 249 | 250 | .. list-table:: Certificate Attributes 251 | :header-rows: 1 252 | 253 | * - Attribute Name 254 | - In CR 255 | - In PR 256 | 257 | * - officer name 258 | - |tick| 259 | - 260 | * - number 261 | - |tick| 262 | - 263 | * - date 264 | - |tick| 265 | - 266 | * - place 267 | - |tick| 268 | - 269 | * - type 270 | - |tick| 271 | - 272 | 273 | .. list-table:: Union Attributes 274 | :header-rows: 1 275 | 276 | * - Attribute Name 277 | - In CR 278 | - In PR 279 | 280 | * - date of union 281 | - |tick| 282 | - 283 | * - place of union 284 | - |tick| 285 | - 286 | * - conjoint1 UIN 287 | - |tick| 288 | - 289 | * - conjoint2 UIN 290 | - |tick| 291 | - 292 | * - date of divorce 293 | - |tick| 294 | - 295 | 296 | .. list-table:: Filiation Attributes 297 | :header-rows: 1 298 | 299 | * - Attribute Name 300 | - In CR 301 | - In PR 302 | 303 | * - parent1 UIN 304 | - |tick| 305 | - 306 | * - parent2 UIN 307 | - |tick| 308 | - 309 | 310 | .. list-table:: Document Type 311 | :header-rows: 1 312 | 313 | * - Document Type 314 | 315 | * - birth certificate 316 | * - death certificate 317 | * - marriage certificate 318 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Secure Identity Alliance (SIA) 2 | 3 | Version 1.0, 31st May 2022 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, modification, and distribution stated in this document. 10 | "Licensor" or “SIA” or “Secure Identity Alliance” shall mean the copyright owner that is granting the License. 11 | "You" (or "Your") shall mean an individual or legal entity exercising permissions granted by this License. 12 | "Work" or “Project” shall mean the work of authorship, including where applicable text, software programming code in object code and/or source code and its documentation, drawings, schemas, figures, and other creations, created in the framework of the OSIA Working Group of the SIA, that is made available under the License, as indicated by a copyright notice that is included in or attached to the Work. 13 | "Derivative Works" shall mean any work, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 14 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is by its author or copyright holder intentionally submitted to Licensor for inclusion in the Work. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work. 15 | "Contributor" shall mean any individual or legal entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 16 | 17 | 2. Grant of copyright License. 18 | This License is applicable to works of authorship created in the framework of the OSIA Working Group that are published as a Work with a reference or link to this License. 19 | By using and/or copying the Work that includes a reference to this License or to which this License is linked, You agree that you have read, understood, and will comply with the terms and conditions of this License. 20 | 21 | 3. License to reproduce and distribute the unmodified Work. 22 | 23 | Subject to the terms and conditions of this License, the Licensor and each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, evaluate, test, reference, implement, display and distribute the unmodified Work, in any medium and for any purpose, provided that You include the following on all the copies of the Work or the portions of the Work that you copy and/or distribute: 24 | * A link or URL to the original Work, clearly visible to any recipient; 25 | * The copyright notice of the Licensor, indicating the SIA as the original copyright owner, in the form: “Copyright © Secure Identity Alliance (2022)”; 26 | * A copy of this License or a link or URL to this License, clearly visible to any recipient. 27 | You must include the copyright notice in any documents, software or any other items or products that you create pursuant to the implementation of the contents of the Work or any portion thereof. 28 | 29 | 4. Modifications. 30 | 31 | The Licensor does not grant You the right to create modifications of the Work or Derivative Works pursuant to this License, except as follows. 32 | Solely in order to facilitate, evaluate or test the implementation of the technical specifications set forth in the Work, You may create and distribute Derivative Works in software and in methods, in documentation of software and methods and in supporting materials accompanying software and methods, provided that all such Derivative Works include the following notices: 33 | Notice of any changes or modifications to the WORK ; 34 | The following copyright statement: 35 | “Copyright © (the name of Your organization) (year) 36 | This software or document includes material copied from or derived from [title and URL of the Work] 37 | Copyright © Secure Identity Alliance (2022)” 38 | 39 | However, the publication, display, or distribution of Derivative Works for use as a technical standard or specification, or any representation thereof as a technical specification, is expressly prohibited unless such use is expressly allowed by the Licensor to You in writing. 40 | 41 | 5. Distribution of Derivative Works. 42 | 43 | You may reproduce, display and distribute copies of the Work and/or Derivative Works thereof (which are allowed in accordance with clause 4), in any medium, provided that You meet the following conditions: 44 | * You must give any recipients of the Derivative Works a copy of this License, clearly visible to the recipient; 45 | * You must cause any modified files to carry prominent notices stating that You changed the files of the Work. 46 | * You must provide a link or URL to the original Work and the most recent version thereof, clearly visible to any recipient; 47 | * You must provide the copyright notice as set forth in clause 4. 48 | 49 | 6. Submission of Contributions. 50 | 51 | You may submit proposed Contributions to the Licensor for inclusion in the Work. By doing so, You intend to contribute to the further development of the Work. 52 | Any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License. Any submitted Contributions may be included in the Work by Licensor after review and approval by Licensor in accordance with Licensor’s policies and decision-making processes. Only Licensor is entitled to publish a modified version of the Work including Your Contributions, without prejudice to Your limited right to create modifications and Derivative Works as allowed under Clause 4. 53 | You assign to the Licensor Your right, title, and interest, including Your rights under copyright, in Your Contributions, for all present and future forms of exploitation and use, and in all technological solutions, at no cost. 54 | If and insofar transfer or assignment of Your rights is not validly possible, You hereby grant to the SIA, its Members and to recipients of the Work distributed by the SIA, a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such Derivative Works. Furthermore, You grant a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, sell, lease, or otherwise convey or make available the Work and implementations of the Work, including Your Contributions, where patent claims would be infringed by such use and/or such implementation. You declare that You will not use any patent claim nor any other intellectual property right to undermine the effect of such assignment. 55 | You represent that you believe in good faith that Your Contributions are Your original creations and that You have sufficient right to submit these for inclusion in the Work. 56 | 57 | 7. Trademarks. 58 | 59 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work. 60 | 61 | 8. Disclaimer of warranty. 62 | 63 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 64 | 65 | 9. Limitation of liability. 66 | 67 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless and insofar required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall Licensor or any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if Licensor or such Contributor has been advised of the possibility of such damages. 68 | 69 | 10. Accepting warranty or additional liability. 70 | 71 | While distributing the Work or (insofar allowed) Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. 72 | However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of Licensor or any other Contributor, and only if You agree to indemnify, defend, and hold Licensor and each Contributor harmless for any liability incurred by, or claims asserted against, Licensor and such Contributor by reason of Your accepting any such warranty or additional liability. 73 | 74 | 11. License versions. 75 | 76 | The SIA is the publisher of this License and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. No one other has the right to modify this License. 77 | 78 | 12. Severability. 79 | 80 | If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. 81 | 82 | 13. Applicable law and jurisdiction. 83 | 84 | This License shall be governed by the law of the jurisdiction specified in a notice contained within the Work, except to the extent that any applicable law provides otherwise. Any litigation relating to this License shall be subject to the jurisdiction of the courts of the jurisdiction and venue specified in a notice contained in the Work. 85 | 86 | 87 | Copyright © Secure Identity Alliance (2022) 88 | 89 | 90 | END OF TERMS AND CONDITIONS 91 | -------------------------------------------------------------------------------- /src/doc/annexes/license.rst: -------------------------------------------------------------------------------- 1 | License 2 | ======= 3 | 4 | Secure Identity Alliance (SIA) 5 | 6 | Version 1.0, 31st May 2022 7 | 8 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 9 | 10 | 1. Definitions. 11 | 12 | "License" shall mean the terms and conditions for use, reproduction, modification, and distribution stated in this document. 13 | 14 | "Licensor" or “SIA” or “Secure Identity Alliance” shall mean the copyright owner that is granting the License. 15 | 16 | "You" (or "Your") shall mean an individual or legal entity exercising permissions granted by this License. 17 | 18 | "Work" or “Project” shall mean the work of authorship, including where applicable text, software programming code in object code and/or source code and its documentation, drawings, schemas, figures, and other creations, created in the framework of the OSIA Working Group of the SIA, that is made available under the License, as indicated by a copyright notice that is included in or attached to the Work. 19 | 20 | "Derivative Works" shall mean any work, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. 21 | 22 | "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is by its author or copyright holder intentionally submitted to Licensor for inclusion in the Work. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work. 23 | 24 | "Contributor" shall mean any individual or legal entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 25 | 26 | 2. Grant of copyright License. 27 | 28 | This License is applicable to works of authorship created in the framework of the OSIA Working Group that are published as a Work with a reference or link to this License. 29 | By using and/or copying the Work that includes a reference to this License or to which this License is linked, You agree that you have read, understood, and will comply with the terms and conditions of this License. 30 | 31 | 3. License to reproduce and distribute the unmodified Work. 32 | 33 | Subject to the terms and conditions of this License, the Licensor and each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, evaluate, test, reference, implement, display and distribute the unmodified Work, in any medium and for any purpose, provided that You include the following on all the copies of the Work or the portions of the Work that you copy and/or distribute: 34 | 35 | * A link or URL to the original Work, clearly visible to any recipient; 36 | * The copyright notice of the Licensor, indicating the SIA as the original copyright owner, in the form: “Copyright © Secure Identity Alliance (2022)”; 37 | * A copy of this License or a link or URL to this License, clearly visible to any recipient. 38 | 39 | You must include the copyright notice in any documents, software or any other items or products that you create pursuant to the implementation of the contents of the Work or any portion thereof. 40 | 41 | 4. Modifications. 42 | 43 | The Licensor does not grant You the right to create modifications of the Work or Derivative Works pursuant to this License, except as follows. 44 | 45 | Solely in order to facilitate, evaluate or test the implementation of the technical specifications set forth in the Work, You may create and distribute Derivative Works in software and in methods, in documentation of software and methods and in supporting materials accompanying software and methods, provided that all such Derivative Works include the following notices: 46 | 47 | Notice of any changes or modifications to the WORK ; 48 | 49 | The following copyright statement: 50 | 51 | | "Copyright © (the name of Your organization) (year) 52 | | This software or document includes material copied from or derived from [title and URL of the Work] 53 | | Copyright © Secure Identity Alliance (2022)"" 54 | 55 | However, the publication, display, or distribution of Derivative Works for use as a technical standard or specification, or any representation thereof as a technical specification, is expressly prohibited unless such use is expressly allowed by the Licensor to You in writing. 56 | 57 | 5. Distribution of Derivative Works. 58 | 59 | You may reproduce, display and distribute copies of the Work and/or Derivative Works thereof (which are allowed in accordance with clause 4), in any medium, provided that You meet the following conditions: 60 | * You must give any recipients of the Derivative Works a copy of this License, clearly visible to the recipient; 61 | * You must cause any modified files to carry prominent notices stating that You changed the files of the Work. 62 | * You must provide a link or URL to the original Work and the most recent version thereof, clearly visible to any recipient; 63 | * You must provide the copyright notice as set forth in clause 4. 64 | 65 | 6. Submission of Contributions. 66 | 67 | You may submit proposed Contributions to the Licensor for inclusion in the Work. By doing so, You intend to contribute to the further development of the Work. 68 | 69 | Any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License. Any submitted Contributions may be included in the Work by Licensor after review and approval by Licensor in accordance with Licensor’s policies and decision-making processes. Only Licensor is entitled to publish a modified version of the Work including Your Contributions, without prejudice to Your limited right to create modifications and Derivative Works as allowed under Clause 4. 70 | 71 | You assign to the Licensor Your right, title, and interest, including Your rights under copyright, in Your Contributions, for all present and future forms of exploitation and use, and in all technological solutions, at no cost. 72 | 73 | If and insofar transfer or assignment of Your rights is not validly possible, You hereby grant to the SIA, its Members and to recipients of the Work distributed by the SIA, a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Your Contributions and such Derivative Works. Furthermore, You grant a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have made, use, sell, lease, or otherwise convey or make available the Work and implementations of the Work, including Your Contributions, where patent claims would be infringed by such use and/or such implementation. You declare that You will not use any patent claim nor any other intellectual property right to undermine the effect of such assignment. 74 | 75 | You represent that you believe in good faith that Your Contributions are Your original creations and that You have sufficient right to submit these for inclusion in the Work. 76 | 77 | 7. Trademarks. 78 | 79 | This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work. 80 | 81 | 8. Disclaimer of warranty. 82 | 83 | Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 84 | 85 | 9. Limitation of liability. 86 | 87 | In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless and insofar required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall Licensor or any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if Licensor or such Contributor has been advised of the possibility of such damages. 88 | 89 | 10. Accepting warranty or additional liability. 90 | 91 | While distributing the Work or (insofar allowed) Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. 92 | 93 | However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of Licensor or any other Contributor, and only if You agree to indemnify, defend, and hold Licensor and each Contributor harmless for any liability incurred by, or claims asserted against, Licensor and such Contributor by reason of Your accepting any such warranty or additional liability. 94 | 95 | 11. License versions. 96 | 97 | The SIA is the publisher of this License and may publish revised and/or new versions of this License from time to time. Each version will be given a distinguishing version number. No one other has the right to modify this License. 98 | 99 | 12. Severability. 100 | 101 | If any provision of this License is held to be unenforceable, such provision shall be reformed only to the extent necessary to make it enforceable. 102 | 103 | 13. Applicable law and jurisdiction. 104 | 105 | This License shall be governed by the law of the jurisdiction specified in a notice contained within the Work, except to the extent that any applicable law provides otherwise. Any litigation relating to this License shall be subject to the jurisdiction of the courts of the jurisdiction and venue specified in a notice contained in the Work. 106 | 107 | 108 | Copyright © Secure Identity Alliance (2022) 109 | 110 | 111 | END OF TERMS AND CONDITIONS 112 | -------------------------------------------------------------------------------- /src/doc/01 - intro.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _chapter-intro: 3 | 4 | Introduction 5 | ============ 6 | 7 | Identity systems that are built on specific vendor solutions lack interoperability among 8 | the main system modules. Lack of vendor and technology interoperability causes difficulties 9 | in replacing a building block of an identity management system from vendor A with an equivalent 10 | building block from vendor B or when expanding the scope of an existing system by linking to 11 | new building blocks. The main technology barrier is the lack of standardized interfaces (APIs). 12 | Building blocks are often unable to communicate with each other due to varying interfaces (APIs) 13 | and data formats, making it difficult to swap out building blocks or add new ones to the system. 14 | 15 | This |specification| describes a set of standardized application program interfaces (APIs) needed 16 | to connect the multiple building blocks of an identity management solution. 17 | 18 | Problem Statement: lack of interoperability in identity systems 19 | --------------------------------------------------------------- 20 | 21 | .. only:: not itu 22 | 23 | Target 16.9 of the UN Sustainable Development Goals is to "provide legal identity for all, 24 | including birth registration" by the year 2030. But there is a major barrier: the lack of vendor/provider 25 | and technology neutrality - commonly known as "vendor lock-in". 26 | 27 | Lack of vendor and technology neutrality causes difficulties in replacing a building block of an 28 | identity management system from vendor A with an equivalent building block from vendor B, 29 | or expand the scope of an existing system by linking to new building blocks. 30 | The main technology barrier is the lack of standardized interfaces (APIs). 31 | Building blocks are often unable to communicate with each other due to varying interfaces (APIs) 32 | and data formats, making it difficult to swap out building blocks or add new ones to the system. 33 | 34 | This |specification| addresses the vendor lock-in concern by providing a set of standardized interfaces 35 | needed to connect the multiple building blocks of an identity management system. 36 | 37 | .. note:: 38 | 39 | The specified APIs in this |specification| can cover different use cases based on an organization requirement. 40 | The implementation of APIs in this |specification| should adhere to relevant security and compliance standards 41 | within an organization based on its security policy. Care should be taken to ensure that the APIs are secured 42 | with proper access control to ensure the privacy of user identities. The trust of the data 43 | as used in this |specification| is a function of the data source which means that authoritative sources 44 | such as government sources will be highly reliable. 45 | 46 | The OSIA Initiative 47 | ------------------- 48 | 49 | Launched by the not-for-profit Secure Identity Alliance, *Open Standard Identity APIs* (OSIA) is an 50 | initiative created for the public good to address vendor lock-in problem. 51 | 52 | OSIA addresses the vendor lock-in concern by providing a simple, open standards-based connectivity 53 | layer between all key building blocks within the national identity ecosystem. 54 | 55 | OSIA scope is as follows: 56 | 57 | 1. **Build a common understanding of the functional scope for identity systems building blocks** - NON PRESCRIPTIVE 58 | 59 | OSIA's first step has been to formalize the definitions, scope, and main functionalities of each 60 | building block within the identity management system. 61 | 62 | 2. **Create a set of standardized interfaces and data dictionary** - PRESCRIPTIVE 63 | 64 | For this core piece of work, OSIA is focused on developing the set of interfaces and standardized 65 | data dictionary needed to connect the multiple identity system building blocks and ensure seamless 66 | interactions via pre-defined services. 67 | 68 | It is then down to each government to define and implement the interaction processes between individual 69 | building blocks (which in turn determines which interfaces are associated with each building block), 70 | according to local laws and regulations. 71 | 72 | With OSIA, governments are free to select the building blocks they need, from the suppliers they choose - without fear of lock in. 73 | 74 | And because OSIA operates at the interface layer, interoperability is assured without the need to 75 | rearchitect environments or rebuild solutions from the ground up. ID ecosystem building blocks are 76 | simply swapped in and out as the use case demands - from best-of-breed options already available on the market. 77 | 78 | This real-world approach dramatically reduces operational and financial risk, increases the effectiveness 79 | of existing identity ecosystems, and rapidly moves government initiatives from proof of concept to live environments. 80 | 81 | OSIA Benefits 82 | ------------- 83 | 84 | The OSIA initiative offers a wide range of benefits to implementers of national ID management solutions. 85 | 86 | 1. **Unleash market innovation** 87 | 88 | OSIA establishes the conditions that support an equal marketplace and makes it possible for the wider 89 | identity community to collaborate in new ways. 90 | 91 | * Create a marketplace where all vendors can compete equally: OSIA operates at the interface layer 92 | and does not define - or therefore favor - any technology at the building block layer 93 | (which is typically where the differentiation among vendors takes place). 94 | 95 | * Support the emergence of new local market models featuring local suppliers and SMEs: 96 | like the Open Banking revolution, OSIA exposes high performing standardized interfaces that 97 | enable new use cases and market offers - from the simple to the complex. 98 | 99 | * Ensure product(s) compatibility after Mergers & Acquisitions: Market consolidation can often 100 | lead to major products being put into maintenance - leaving governments with little choice 101 | but to replace these. With OSIA, whatever the status of a product, it will continue to be 102 | interoperable with new offers. 103 | 104 | 2. **Enable identity as a service** 105 | 106 | OSIA empowers governments to build new inclusive eGovernment solutions that give citizens ease of 107 | access to public services or trusted digital ID schemes that extend the use of citizen ID into 108 | other online areas - such as banking and payments. 109 | 110 | * Driving digital ID market growth: OSIA facilitates the link between sovereign identity management 111 | solutions and digital identity solutions, like mobile ID, by standardizing the ad hoc interfaces 112 | that decouple providers of the ID management solution and the digital ID solution. 113 | 114 | * Reducing fraud within siloed databases/multiple ID systems: OSIA enables the secure and 115 | controlled flow of data and services, like ID deduplication and authentication, across multiple 116 | foundational and functional registries - even where these registries are run by separate 117 | ministries and government agencies. 118 | 119 | Governments are able to reduce public sector payroll fraud, leakage in social benefits, fraud associated 120 | with tax filing and ensure the integrity of the electoral process. 121 | 122 | 3. **Address integrator/vendor lock-in** 123 | 124 | OSIA enables governments to exert full control over their sovereign identity systems. So, they can 125 | pursue their national development agendas - without any fear of integrator/ vendor lock-in. 126 | Governments are no longer forced to implement a wall-to-wall solution from a single vendor and 127 | will not encounter compatibility difficulties when evolving their existing legacy solutions. 128 | They can: 129 | 130 | * Implement multi-vendor programs by mixing selected building blocks from different suppliers. 131 | * Extend legacy solutions or replace legacy building blocks(s) with a new building block(s) 132 | from a different supplier(s). 133 | 134 | Diffusion, Audience, and Access 135 | ------------------------------- 136 | 137 | This |specification| is hosted in `GitHub `_ and can be 138 | downloaded from `ReadTheDocs `_. 139 | 140 | This |specification| is licensed under `The SIA License `_. 141 | 142 | Any country, technology partner or individual is free to download the functional and technical specifications to implement it in their customized foundational and sectoral ID systems or building blocks. Governments can also reference OSIA as Open Standards in tenders.Any country, technology partner or individual is free to download the functional and technical specifications to implement it in their customized foundational and sectoral ID systems or building blocks. Governments can also reference OSIA as Open Standards in tenders. 143 | 144 | For more information on how to reference OSIA please see Section :ref:`osia-versions-ref`. 145 | 146 | Convention and Typographical Rules 147 | ---------------------------------- 148 | 149 | The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and 150 | "OPTIONAL" in this document are to be interpreted as described in `RFC 2119 `_. 151 | 152 | In the body of this |specification|, the words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", 153 | "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" are to be interpreted as described in [IETF `RFC 2119 `_]. 154 | 155 | 1. MUST: This word, or the terms "REQUIRED" or "SHALL", mean that the definition is an absolute requirement of the specification. 156 | 2. MUST NOT: This phrase, or the phrase "SHALL NOT", mean that the definition is an absolute prohibition of the specification. 157 | 3. SHOULD: This word, or the adjective "RECOMMENDED", mean that there may exist valid reasons in particular circumstances 158 | to ignore a particular item, but the full implications must be understood and carefully weighed before choosing a different course. 159 | 4. SHOULD NOT: This phrase, or the phrase "NOT RECOMMENDED" mean that there may exist valid reasons in particular circumstances 160 | when the particular behaviour is acceptable or even useful, but the full implications should be understood, and the case carefully weighed before implementing any behaviour described with this label. 161 | 5. MAY: This word, or the adjective "OPTIONAL", mean that an item is truly optional. 162 | 163 | .. only:: itu 164 | 165 | A vendor may choose to include the item because a particular marketplace requires it or because the vendor feels that it enhances 166 | the product while another vendor may omit the same item. An implementation which does not include a particular option MUST 167 | be prepared to interoperate with another implementation which does include the option, though perhaps with reduced functionality. 168 | In the same vein, an implementation which does include a particular option MUST be prepared to interoperate with another 169 | implementation which does not include the option (except, of course, for the feature the option provides.) 170 | 171 | 172 | Code samples highlighted in blocks appear like that: 173 | 174 | .. code-block:: json 175 | 176 | { 177 | "key": "value", 178 | "another_key": 23 179 | } 180 | 181 | -------------------------------------------------------------------------------- /src/doc/functional/_cms.rst: -------------------------------------------------------------------------------- 1 | 2 | Credential Services 3 | ------------------- 4 | 5 | This interface describes services to manage credentials and credential 6 | requests in the context of an identity system. 7 | 8 | Services 9 | """""""" 10 | 11 | .. py:function:: createCredentialRequest(personID, credentialProfileID, additionalData, transactionID) 12 | :noindex: 13 | 14 | Request issuance of a secure credential. 15 | 16 | **Authorization**: ``cms.request.write`` 17 | 18 | :param str personID: The ID of the person. 19 | :param str credentialProfileID: The ID of the credential profile to issue to the person. 20 | :param dict additionalData: Additional data relating to the requested credential profile, 21 | e.g. credential lifetime if overriding default, delivery addresses, etc. 22 | :param string transactionID: The client generated transactionID. 23 | :return: a status indicating success or error. In the case of success, a credential request identifier. 24 | 25 | .. py:function:: readCredentialRequest(credentialRequestID, attributes, transactionID) 26 | :noindex: 27 | 28 | Retrieve the data/status of a credential request. 29 | 30 | **Authorization**: ``cms.request.read`` 31 | 32 | :param str credentialRequestID: The ID of the credential request. 33 | :param set attributes: The (optional) set of required attributes to retrieve. 34 | :param string transactionID: The client generated transactionID. 35 | :return: a status indicating success or error, and in case of success the issuance data/status. 36 | 37 | .. py:function:: updateCredentialRequest(credentialRequestID, additionalData, transactionID) 38 | :noindex: 39 | 40 | Update the requested issuance of a secure credential. 41 | 42 | **Authorization**: ``cms.request.write`` 43 | 44 | :param str credentialRequestID: The ID of the credential request. 45 | :param string transactionID: The client generated transactionID. 46 | :param dict additionalData: Additional data relating to the requested credential profile, 47 | e.g. credential lifetime if overriding default, delivery addresses, etc. 48 | :return: a status indicating success or error. 49 | 50 | .. py:function:: cancelCredentialRequest(credentialRequestID, transactionID) 51 | :noindex: 52 | 53 | Cancel the requested issuance of a secure credential. 54 | 55 | **Authorization**: ``cms.request.write`` 56 | 57 | :param str credentialRequestID: The ID of the credential request. 58 | :param string transactionID: The client generated transactionID. 59 | :return: a status indicating success or error. 60 | 61 | ---------- 62 | 63 | .. py:function:: findCredentials(expressions, transactionID) 64 | :noindex: 65 | 66 | Retrieve a list of credentials that match the passed in search criteria. 67 | 68 | **Authorization**: ``cms.credential.read`` 69 | 70 | :param list[(str,str,str)] expressions: The expressions to evaluate. Each 71 | expression is described with the attribute's name, the operator 72 | (one of ``<``, ``>``, ``=``, ``>=``, ``<=``) and the attribute value. 73 | :param string transactionID: The client generated transactionID. 74 | :return: a status indicating success or error, in the case of success the 75 | list of matching credentials. 76 | 77 | .. py:function:: readCredential(credentialID, attributes, transactionID) 78 | :noindex: 79 | 80 | Retrieve the attributes/status of an issued credential. A wide range of 81 | information may be returned, dependant on the type of credential that was 82 | issued, smart card, mobile, passport, etc. 83 | 84 | **Authorization**: ``cms.credential.read`` 85 | 86 | :param str credentialID: The ID of the credential. 87 | :param set attributes: The (optional) set of required attributes to retrieve. 88 | :param string transactionID: The client generated transactionID. 89 | :return: a status indicating success or error, in the case of success the 90 | requested data will be returned. 91 | 92 | .. py:function:: updateCredential(credentialID, credentialData, transactionID) 93 | :noindex: 94 | 95 | Update some of the attributes of an issued credential. Only a limited set 96 | of attributes may be changed, for example expiry date, issuing place, etc. 97 | 98 | **Authorization**: ``cms.credential.write`` 99 | 100 | :param str credentialID: The ID of the credential. 101 | :param dict credentialData: The new value of the credential data. 102 | :param string transactionID: The client generated transactionID. 103 | :return: a status indicating success or error, in the case of success the 104 | requested data will be returned. 105 | 106 | .. py:function:: suspendCredential(credentialID, additionalData, transactionID) 107 | :noindex: 108 | 109 | Suspend an issued credential. For electronic credentials this will suspend any 110 | PKI certificates that are present. 111 | 112 | **Authorization**: ``cms.credential.write`` 113 | 114 | :param str credentialID: The ID of the credential. 115 | :param dict additionalData: Additional data relating to the request, 116 | e.g. reason for suspension. 117 | :param string transactionID: The (optional) client generated transactionID. 118 | :return: a status indicating success or error. 119 | 120 | .. py:function:: unsuspendCredential(credentialID, additionalData, transactionID) 121 | :noindex: 122 | 123 | Unsuspend an issued credential. For electronic credentials this will unsuspend any 124 | PKI certificates that are present. 125 | 126 | **Authorization**: ``cms.credential.write`` 127 | 128 | :param str credentialID: The ID of the credential. 129 | :param dict additionalData: Additional data relating to the request, 130 | e.g. reason for unsuspension. 131 | :param string transactionID: The client generated transactionID. 132 | :return: a status indicating success or error. 133 | 134 | .. py:function:: revokeCredential(credentialID, additionalData, transactionID) 135 | :noindex: 136 | 137 | Revoke an issued credential. For electronic credentials this will revoke any 138 | PKI certificates that are present. 139 | 140 | **Authorization**: ``cms.credential.write`` 141 | 142 | :param str credentialID: The ID of the credential. 143 | :param dict additionalData: Additional data relating to the request, 144 | e.g. reason for revocation. 145 | :param string transactionID: The client generated transactionID. 146 | :return: a status indicating success or error. 147 | 148 | .. py:function:: setCredentialStatus(credentialID, status, reason, requester, comment, transactionID) 149 | :noindex: 150 | 151 | Change the status of a credential. This is an extension of the revoke/suspend services, 152 | supporting more statuses and transitions. 153 | 154 | **Authorization**: ``cms.credential.write`` 155 | 156 | :param str credentialID: The ID of the credential. 157 | :param string status: The new status of the credential 158 | :param string reason: A text describing the cause of the change of status 159 | :param string requester: The client generated transactionID. 160 | :param string comment: A free text comment 161 | :param string transactionID: The client generated transactionID. 162 | :return: a status indicating success or error. 163 | 164 | ---------- 165 | 166 | .. py:function:: findCredentialProfiles(expressions, transactionID) 167 | :noindex: 168 | 169 | Retrieve a list of credential profils that match the passed in search criteria 170 | 171 | **Authorization**: ``cms.profile.read`` 172 | 173 | :param list[(str,str,str)] expressions: The expressions to evaluate. Each expression is described with the attribute's name, the operator (one of ``<``, ``>``, ``=``, ``>=``, ``<=``, ``!=``) and the attribute value 174 | :param string transactionID: The client generated transactionID. 175 | :return: a status indicating success or error, and in case of success the matching credential profile list. 176 | 177 | 178 | Attributes 179 | """""""""" 180 | 181 | The "attributes" parameter used in "read" calls is used to provide a set of 182 | identifiers that limit the amount of data that is returned. 183 | It is often the case that the whole data set is not required, but instead, 184 | a subset of that data. 185 | 186 | Some calls may require new attributes to be defined. E.g. when 187 | retrieving biometric data, the caller may only want the meta data about 188 | that biometric, rather than the actual biometric data. 189 | 190 | Data Model 191 | """""""""" 192 | 193 | .. list-table:: Credential Data Model 194 | :header-rows: 1 195 | :widths: 25 50 25 196 | 197 | * - Type 198 | - Description 199 | - Example 200 | 201 | * - Credential 202 | - The attributes of the credential itself 203 | 204 | The proposed transitions for the status are represented below. It can be adapted if needed. 205 | 206 | .. uml:: 207 | :scale: 30% 208 | 209 | [*] --> new 210 | new --> active: issue 211 | active -> suspended: suspend 212 | suspended -> active: unsuspend 213 | active --> revoked 214 | suspended --> revoked 215 | 216 | - ID, status, dates, serial number 217 | 218 | * - Credential Profile 219 | - This object identifies the type of credential. It is characterized 220 | with a set of attributes such as the version, the number of pages, etc. 221 | 222 | Similar to the rulebook published in the context of digital identity, it could be interesting for 223 | a system implementing OSIA to publish a description of the credential profiles implemented. 224 | - Passport, ID card, Diplomatic passport 225 | * - Biometric Data 226 | - Digital representation of biometric characteristics. 227 | 228 | All images can be passed by value (image buffer is in the request) or by reference (the address of the 229 | image is in the request). 230 | Biometric images can be compliant with ISO 19794 or ISO 39794, which allow multiple encoding and supports additional 231 | metadata specific to fingerprint, palmprint, portrait, iris or signature. 232 | 233 | A biometric data can be associated to no image or a partial image if it includes information about 234 | the missing items (example: one finger may be amputated on a 4 finger image) 235 | - fingerprint, portrait, iris, signature 236 | 237 | * - Biographic Data 238 | - a dictionary (list of names and values) giving the biographic data of interest for the biometric services. 239 | - first name, last name, date of birth, etc. 240 | 241 | * - Request Data 242 | - a dictionary (list of names and values) for data related to the request itself. 243 | - Type of credential, action to execute, priority 244 | 245 | .. uml:: 246 | :caption: Credential Data Model 247 | :scale: 50% 248 | 249 | class Credential { 250 | string credentialID; 251 | string status; 252 | string personID; 253 | string serialNumber; 254 | ... 255 | } 256 | 257 | class CredentialRequest { 258 | string CredentialRequestID; 259 | string status; 260 | string personID; 261 | } 262 | CredentialRequest . Credential 263 | 264 | class BiographicData { 265 | string firstName; 266 | string lastName; 267 | date dateOfBirth; 268 | ... 269 | } 270 | BiographicData -o CredentialRequest 271 | 272 | class BiometricData { 273 | byte[] image; 274 | URL imageRef; 275 | byte[] template; 276 | } 277 | CredentialRequest o-- "*" BiometricData 278 | 279 | class RequestData { 280 | int priority; 281 | string credentialProfileID; 282 | string requestType; 283 | ... 284 | } 285 | RequestData --o CredentialRequest 286 | 287 | -------------------------------------------------------------------------------- /src/doc/06 - building blocks.rst: -------------------------------------------------------------------------------- 1 | 2 | .. _chapter-bb: 3 | 4 | =============== 5 | Building Blocks 6 | =============== 7 | 8 | This chapter defines the interfaces that each building block MAY implement and provides an overview of the high level functionalities that each building block MAY implement. 9 | 10 | This chapter does not define high level functionalities for the following building blocks: 11 | 12 | * Digital Credential Issuance & Distribution System because this building block is out of scope for the current version of OSIA specification v6.1.0. 13 | * Identity Provider because this building block is not expected to implement OSIA interfaces but rather to consume them. 14 | 15 | .. _chapter-bb-func: 16 | 17 | Building Blocks High Level Functionalities 18 | ------------------------------------------ 19 | 20 | The following section describes the high level functionalities that each building block MAY implement. Each building block can find many different implementations in the market while still complying with the requested functional requirements. This differentiation among products is what makes the market competitive and innovative. 21 | 22 | Enrollment 23 | """""""""" 24 | 25 | The Enrollment building block is composed of enrollment client and enrollment server. 26 | 27 | .. figure:: images/enrollment_client.* 28 | 29 | Enrollment Client overview and description of its high level functionalities 30 | 31 | .. figure:: images/enrollment_server.* 32 | 33 | Enrollment Server overview and description of its high level functionalities 34 | 35 | UIN Generator 36 | """"""""""""" 37 | 38 | .. figure:: images/UIN_generator.* 39 | 40 | UIN Generator overview and description of its high level functionalities 41 | 42 | Biometric System (ABIS) 43 | """"""""""""""""""""""" 44 | 45 | .. figure:: images/abis.png 46 | 47 | ABIS overview and description of its high level functionalities 48 | 49 | Population Registry (PR) 50 | """""""""""""""""""""""" 51 | 52 | .. figure:: images/population_registry.* 53 | 54 | Population Registry overview and description of its high level functionalities 55 | 56 | Civil Registry (CR) 57 | """"""""""""""""""" 58 | 59 | .. figure:: images/civil_registry.* 60 | 61 | Civil Registry overview and description of its high level functionalities 62 | 63 | Credential Management System (CMS) 64 | """""""""""""""""""""""""""""""""" 65 | 66 | .. figure:: images/credential_management_system.* 67 | 68 | Credential Management System overview and description of its high level functionalities 69 | 70 | Third Party Services 71 | """""""""""""""""""" 72 | 73 | .. figure:: images/third_party_services.* 74 | 75 | Third Party Service overview and description of its high level functionalities 76 | 77 | Mapping Building Blocks vs Interfaces 78 | ------------------------------------- 79 | 80 | The following table maps the interfaces described in :ref:`chapter-interfaces` against the building blocks described in :ref:`chapter-bb-func`. 81 | 82 | .. table:: Mapping Building Blocks vs Interfaces Mapping 83 | :class: longtable 84 | :widths: 30 10 10 10 10 10 10 10 10 85 | 86 | 87 | ================================= ======= ======= ======= ======= ======= ======= ======= ====================== 88 | .. **Building Blocks** 89 | --------------------------------- ------------------------------------------------------------------------------ 90 | **Interfaces** Enroll Enroll PR UIN Gen ABIS CR CMS Third Party Services 91 | Clt Srv 92 | ================================= ======= ======= ======= ======= ======= ======= ======= ====================== 93 | **Notification** 94 | ----------------------------------------------------------------------------------------------------------------- 95 | Subscribe U U U U 96 | List Subscription U U U U 97 | Unsubscribe U U U U 98 | Confirm U U U U 99 | Create Topic U U U U 100 | List Topics U U U U 101 | Delete Topic U U U U 102 | Publish U U U U 103 | Notify I I I I 104 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 105 | **Data Access** 106 | ----------------------------------------------------------------------------------------------------------------- 107 | Read Person Attributes U IU U IU U 108 | Match Person Attributes U IU IU U 109 | Verify Person Attributes U IU IU U 110 | Query Person UIN U IU IU U 111 | Query Person List U U 112 | Read Document U IU IU U 113 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 114 | **UIN Management** 115 | ----------------------------------------------------------------------------------------------------------------- 116 | Generate UIN U I U 117 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 118 | **Enrollment Services** 119 | ----------------------------------------------------------------------------------------------------------------- 120 | Create Enrollment U I 121 | Read Enrollment U I 122 | Update Enrollment U I 123 | Partial Update Enrollment U I 124 | Finalize Enrollment U I 125 | Delete Enrollment U I 126 | Find Enrollments U I 127 | Send Buffer U I 128 | Get Buffer U I 129 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 130 | **Population Registry Services** 131 | ----------------------------------------------------------------------------------------------------------------- 132 | Find Persons I 133 | Create Person I U U 134 | Read Person I U U U 135 | Update Person I U U 136 | Delete Person I U U 137 | Merge Persons I U 138 | Move Identity I U 139 | Create Identity I 140 | Read Identity I 141 | Update Identity I 142 | Partial Update Identity I 143 | Delete Identity I 144 | Set Identity Status I 145 | Define Reference I 146 | Read Reference I 147 | Read Galleries I 148 | Read Gallery Content I 149 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 150 | **Biometrics** 151 | ----------------------------------------------------------------------------------------------------------------- 152 | Create Encounter U U I 153 | Read Encounter U U I U 154 | Update Encounter U U I 155 | Delete Encounter U U I 156 | Merge Encounters U I 157 | Move Encounters U I 158 | Update Encounter Status U U I 159 | Update Encounter Galleries U U I 160 | Read Template U U I 161 | Read Galleries U U I 162 | Read Gallery Content U U I 163 | Identify U I U 164 | Verify U I U 165 | readTaskStatus U I U 166 | redeliverTaskResult U I U 167 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 168 | **Credential Services** 169 | ----------------------------------------------------------------------------------------------------------------- 170 | Create Credential Request I 171 | Read Credential Request I 172 | Update Credential Request I 173 | Cancel Credential Request I 174 | Find Credentials I 175 | Read Credential I 176 | Update Credential I 177 | Suspend Credential I 178 | Unsuspend Credential I 179 | Revoke Credential I 180 | Set Credential Status I 181 | Find Credential Profiles I 182 | --------------------------------- ------- ------- ------- ------- ------- ------- ------- ---------------------- 183 | **Third Party Services** 184 | ----------------------------------------------------------------------------------------------------------------- 185 | Verify ID I 186 | Identify ID I 187 | Read Attributes I 188 | Read Attributes set I 189 | ================================= ======= ======= ======= ======= ======= ======= ======= ====================== 190 | 191 | -------------------------------------------------------------------------------- /src/doc/functional/_enrollment.rst: -------------------------------------------------------------------------------- 1 | 2 | Enrollment Services 3 | ------------------- 4 | 5 | This interface describes enrollment services in the context of an identity system. It is based on 6 | the following principles: 7 | 8 | - When enrollment is done in one step, the CreateEnrollment can contain all the data and an additional flag (finalize) to indicate all data was collected. 9 | - During the process, enrollment structure can be updated. Only the data that changed need to be transferred. Data not included is left unchanged on the server. In the following example, the biographic data is not changed. 10 | - Images can be passed by value or reference. When passed by value, they are base64-encoded. 11 | - Existing standards are used whenever possible. 12 | 13 | .. admonition:: About documents 14 | 15 | Adding one document or deleting one document implies that: 16 | 17 | - The full document list is read (ReadEnrollment) 18 | - The document list is altered locally to the enrollment client (add or delete) 19 | - The full document list is sent back using the UpdateEnrollment service 20 | 21 | Services 22 | """""""" 23 | 24 | .. py:function:: createEnrollment(enrollmentID, enrollmentTypeId, enrollmentFlags, requestData, contextualData, biometricData, biographicData, documentData, finalize, transactionID) 25 | :noindex: 26 | 27 | Insert a new enrollment. 28 | 29 | **Authorization**: ``enroll.write`` 30 | 31 | :param str enrollmentID: The ID of the enrollment. If the enrollment already exists for the ID an error is returned. 32 | :param str enrollmentTypeId: The enrollment type ID of the enrollment. 33 | :param dict enrollmentFlags: The enrollment custom flags. 34 | :param dict requestData: The enrollment data related to the enrollment itself. 35 | :param dict contextualData: Information about the context of the enrollment 36 | :param list biometricData: The enrollment biometric data. 37 | :param dict biographicData: The enrollment biographic data. 38 | :param list documentData: The enrollment biometric data. 39 | :param str finalize: Flag to indicate that data was collected. 40 | :param string transactionID: The client generated transactionID. 41 | :return: a status indicating success or error. 42 | 43 | .. py:function:: readEnrollment(enrollmentID, attributes, transactionID) 44 | :noindex: 45 | 46 | Retrieve the attributes of an enrollment. 47 | 48 | **Authorization**: ``enroll.read`` 49 | 50 | :param str enrollmentID: The ID of the enrollment. 51 | :param set attributes: The (optional) set of required attributes to retrieve. 52 | :param string transactionID: The client generated transactionID. 53 | :return: a status indicating success or error and in case of success the enrollment data. 54 | 55 | .. py:function:: updateEnrollment(enrollmentID, enrollmentTypeId, enrollmentFlags, requestData, contextualData, biometricData, biographicData, documentData, finalize, transactionID) 56 | :noindex: 57 | 58 | Update an enrollment. 59 | 60 | **Authorization**: ``enroll.write`` 61 | 62 | :param str enrollmentID: The ID of the enrollment. If the enrollment already exists for the ID an error is returned. 63 | :param str enrollmentTypeId: The enrollment type ID of the enrollment. 64 | :param dict enrollmentFlags: The enrollment custom flags. 65 | :param dict requestData: The enrollment data related to the enrollment itself. 66 | :param dict contextualData: Information about the context of the enrollment 67 | :param list biometricData: The enrollment biometric data, this can be partial data. 68 | :param dict biographicData: The enrollment biographic data. 69 | :param list documentData: The enrollment biometric data, this can be partial data. 70 | :param str finalize: Flag to indicate that data was collected. 71 | :param string transactionID: The client generated transactionID. 72 | :return: a status indicating success or error. 73 | 74 | .. py:function:: partialupdateEnrollment(enrollmentID, enrollmentTypeId, enrollmentFlags, requestData, contextualData, biometricData, biographicData, documentData, finalize, transactionID) 75 | :noindex: 76 | 77 | Update part of an enrollment. Not all attributes are mandatory. The payload 78 | is defined as per :rfc:`7396`. 79 | 80 | **Authorization**: ``enroll.write`` 81 | 82 | :param str enrollmentID: The ID of the enrollment. If the enrollment already exists for the ID an error is returned. 83 | :param str enrollmentTypeId: The enrollment type ID of the enrollment. 84 | :param dict enrollmentFlags: The enrollment custom flags. 85 | :param dict requestData: The enrollment data related to the enrollment itself. 86 | :param dict contextualData: Information about the context of the enrollment 87 | :param list biometricData: The enrollment biometric data, this can be partial data. 88 | :param dict biographicData: The enrollment biographic data. 89 | :param list documentData: The enrollment biometric data, this can be partial data. 90 | :param str finalize: Flag to indicate that data was collected. 91 | :param string transactionID: The client generated transactionID. 92 | :return: a status indicating success or error. 93 | 94 | .. py:function:: finalizeEnrollment(enrollmentID, transactionID) 95 | :noindex: 96 | 97 | When all the enrollment steps are done, the enrollment client indicates to the enrollment server that all data has been collected and that any further processing can be triggered. 98 | 99 | **Authorization**: ``enroll.write`` 100 | 101 | :param str enrollmentID: The ID of the enrollment. 102 | :param string transactionID: The client generated transactionID. 103 | :return: a status indicating success or error. 104 | 105 | .. py:function:: deleteEnrollment(enrollmentID, transactionID) 106 | :noindex: 107 | 108 | Deletes the enrollment 109 | 110 | **Authorization**: ``enroll.write`` 111 | 112 | :param str enrollmentID: The ID of the enrollment. 113 | :param string transactionID: The client generated transactionID. 114 | :return: a status indicating success or error. 115 | 116 | .. py:function:: findEnrollments(expressions, offset, limit, transactionID) 117 | :noindex: 118 | 119 | Retrieve a list of enrollments which match passed in search criteria. 120 | 121 | **Authorization**: ``enroll.read`` 122 | 123 | :param list[(str,str,str)] expressions: The expressions to evaluate. Each expression is described with the attribute's name, the operator (one of ``<``, ``>``, ``=``, ``>=``, ``<=``) and the attribute value 124 | :param int offset: The offset of the query (first item of the response) (optional, default to ``0``) 125 | :param int limit: The maximum number of items to return (optional, default to ``100``) 126 | :param string transactionID: The client generated transactionID. 127 | :return: a status indicating success or error and in case of success the matching enrollment list. 128 | 129 | .. py:function:: createBuffer(enrollmentId, data, digest) 130 | :noindex: 131 | 132 | This service is used to send separately the buffers of the images. Buffers can be sent any time from the enrollment client prior to the create or update. 133 | 134 | **Authorization**: ``enroll.buf.write`` 135 | 136 | :param str enrollmentID: The ID of the enrollment. 137 | :param image data: The buffer data. 138 | :param string transactionID: The client generated transactionID. 139 | :param string digest: The digest (hash) of the buffer used by the server to check the integrity of the data received. 140 | :return: a status indicating success or error and in case of success the buffer ID. 141 | 142 | .. py:function:: readBuffer(enrollmentId, bufferId) 143 | :noindex: 144 | 145 | This service is used to get the data of a buffer. 146 | 147 | **Authorization**: ``enroll.buf.read`` 148 | 149 | :param str enrollmentID: The ID of the enrollment. 150 | :param str bufferID: The ID of the buffer. 151 | :param string transactionID: The client generated transactionID. 152 | :return: a status indicating success or error and in case of success the data of the buffer and a digest. 153 | 154 | Attributes 155 | """""""""" 156 | 157 | The "attributes" parameter used in "read" calls is used to provide a set of 158 | identifiers that limit the amount of data that is returned. 159 | It is often the case that the whole data set is not required, but instead, 160 | a subset of that data. 161 | Where possible, existing standards based identifiers should be used for the 162 | attributes to retrieve. 163 | 164 | E.g. For surname/familyname, use OID 2.5.4.4 or id-at-surname. 165 | 166 | Some calls may require new attributes to be defined. E.g. when 167 | retrieving biometric data, the caller may only want the meta data about 168 | that biometric, rather than the actual biometric data. 169 | 170 | Transaction ID 171 | """""""""""""" 172 | 173 | The ``transactionID`` is a string provided by the client application to identity 174 | the request being submitted. It can be used for tracing and debugging. 175 | 176 | 177 | Data Model 178 | """""""""" 179 | 180 | .. list-table:: Enrollment Data Model 181 | :header-rows: 1 182 | :widths: 25 50 25 183 | 184 | * - Type 185 | - Description 186 | - Example(s) 187 | 188 | * - Enrollment 189 | - The full set of data which are captured for one purpose. 190 | - N/A 191 | 192 | * - Document Data 193 | - The documents used as an element of proof for part of the enrollment data. 194 | - Birth certificate, invoice. 195 | 196 | * - Biometric Data 197 | - Digital representation of biometric characteristics. 198 | 199 | All images can be passed by value (image buffer is in the request) or by reference (the address of the 200 | image is in the request). 201 | Biometric images can be compliant with ISO 19794 or ISO 39794, which allow multiple encoding and supports additional 202 | metadata specific to fingerprint, palmprint, portrait, iris or signature. 203 | 204 | A biometric data can be associated to no image or a partial image if it includes information about 205 | the missing items (example: one finger may be amputated on a 4 finger image) 206 | - fingerprint, portrait, iris, signature 207 | 208 | * - Biographic Data 209 | - A dictionary (list of names and values) giving the biographic data of the identity 210 | - ``firstName``, ``lastName``, ``dateOfBirth``, etc. 211 | 212 | * - Enrollment Flags 213 | - a dictionary (list of names and values) for custom flags controlling the enrollment process. 214 | - maximum time allowed to finish the enrollment, etc. 215 | 216 | * - Request Data 217 | - a dictionary (list of names and values) for data related to the process initiated by the enrollment. 218 | - type of request, priority of execution, type of credential to produce, etc. 219 | 220 | * - Contextual Data 221 | - A dictionary (list of names and values) for data related to the enrollment itself 222 | - ``operatorName``, ``enrollmentDate``, etc. 223 | 224 | * - Attributes 225 | - Generic name for any information collected during an enrollment. 226 | Attributes can apply on biographic data, document data, request data, or enrollment flag data. 227 | - ``firstName``, ``lastName``, ``enrollmentDate``, etc. 228 | 229 | * - Expressions 230 | - An expression combines an attribute's name, an operator (one of ``<``, ``>``, ``=``, ``>=``, ``<=``, ``!=``) and a value. 231 | It is used in search services. 232 | - ``firstName=John`` 233 | 234 | .. uml:: 235 | :caption: Enrollment Data Model 236 | :scale: 50% 237 | 238 | class Enrollment { 239 | string enrollmentID; 240 | } 241 | 242 | class ContextualData { 243 | string operator; 244 | date date; 245 | ... 246 | } 247 | Enrollment o- ContextualData 248 | 249 | class BiographicData { 250 | string field1; 251 | int field2; 252 | date field3; 253 | ... 254 | } 255 | BiographicData -o Enrollment 256 | 257 | class BiometricData { 258 | byte[] image; 259 | URL imageRef; 260 | } 261 | Enrollment o-- "*" BiometricData 262 | 263 | class DocumentData { 264 | int documentType; 265 | } 266 | Enrollment o-- "*" DocumentData 267 | 268 | class DocumentPart { 269 | byte[] image; 270 | URL imageRef; 271 | } 272 | DocumentData o-- "*" DocumentPart 273 | 274 | class RequestData { 275 | string field1; 276 | int field2; 277 | date field3; 278 | ... 279 | } 280 | RequestData --o Enrollment 281 | 282 | class EnrollmentFlagsData { 283 | string field1; 284 | int field2; 285 | date field3; 286 | ... 287 | } 288 | EnrollmentFlagsData --o Enrollment 289 | -------------------------------------------------------------------------------- /src/doc/yaml/notification.yaml: -------------------------------------------------------------------------------- 1 | 2 | # (c) Secure Identity Alliance 3 | 4 | openapi: 3.0.0 5 | info: 6 | description: > 7 | The OSIA Notification Interface. 8 | 9 | Notifications are guaranteed to be delivered at least once. In some situation, 10 | it is possible they are delivered twice. 11 | 12 | Change log: 13 | 14 | - 1.2.0: 15 | - Add error structure on 400 errors 16 | - Force additionalProperties to false when extension is not allowed 17 | - 1.1.0: 18 | - Addition of security 19 | - Rename operation ID to be consistent with the other services 20 | - 1.0.0: Initial version 21 | 22 | version: 1.2.0 23 | title: OSIA Notification Interface 24 | license: 25 | name: SIA 26 | url: "https://raw.githubusercontent.com/SecureIdentityAlliance/osia/master/LICENSE" 27 | tags: 28 | - name: Subscriber 29 | - name: Publisher 30 | servers: 31 | - url: https://notification.com/ 32 | paths: 33 | /v1/subscriptions: 34 | post: 35 | summary: Subscribe to a topic 36 | description: | 37 | Subscribes a client to receive event notification. 38 | 39 | Subscriptions are idempotent. Subscribing twice for the same topic and 40 | endpoint (protocol, address) will return the same subscription ID and the 41 | subscriber will receive only once the notifications. 42 | security: 43 | - BearerAuth: [notif.sub.write] 44 | operationId: subscribe 45 | tags: 46 | - Subscriber 47 | parameters: 48 | - name: topic 49 | in: query 50 | required: true 51 | description: The name of the topic for which notifications will be sent 52 | schema: 53 | type: string 54 | - name: protocol 55 | in: query 56 | required: false 57 | description: The protocol used to send the notification 58 | schema: 59 | type: string 60 | enum: [http, email] 61 | - name: address 62 | in: query 63 | required: true 64 | description: the endpoint address, where the notifications will be sent. 65 | schema: 66 | type: string 67 | example: https://tonys-server.com 68 | - name: policy 69 | in: query 70 | required: false 71 | description: | 72 | The delivery policy, expressing what happens when the message cannot be delivered. 73 | 74 | If not specified, retry will be done every hour for 7 days. 75 | 76 | The value is a set of integer separated by comma: 77 | 78 | - countdown: the number of seconds to wait before retrying. Default: 3600. 79 | - max: the maximum max number of retry. -1 indicates infinite retry. Default: 168 80 | schema: 81 | type: string 82 | example: "3600,-1" 83 | responses: 84 | 200: 85 | description: Subscription successfully created. Waiting for confirmation message. 86 | content: 87 | application/json: 88 | schema: 89 | $ref: '#/components/schemas/Subscription' 90 | 400: 91 | description: Bad request 92 | content: 93 | application/json: 94 | schema: 95 | $ref: '#/components/schemas/Error' 96 | 500: 97 | description: Unexpected error 98 | content: 99 | application/json: 100 | schema: 101 | $ref: '#/components/schemas/Error' 102 | 103 | callbacks: 104 | onEvent: 105 | # when event is sent, it will be sent to the `address` provided 106 | # when making the subscription 107 | '{$request.query.address}': 108 | post: 109 | operationId: notificationCB 110 | parameters: 111 | - name: message-type 112 | in: header 113 | required: true 114 | description: the type of the message 115 | schema: 116 | type: string 117 | enum: [SubscriptionConfirmation,Notification] 118 | - name: subscription-id 119 | in: header 120 | required: false 121 | description: the unique ID of the subscription 122 | schema: 123 | type: string 124 | - name: message-id 125 | in: header 126 | required: true 127 | description: the unique ID of the message 128 | schema: 129 | type: string 130 | - name: topic-id 131 | in: header 132 | required: true 133 | description: the unique ID of the topic 134 | schema: 135 | type: string 136 | requestBody: 137 | description: The message 138 | content: 139 | application/json: 140 | schema: 141 | $ref: '#/components/schemas/Message' 142 | responses: 143 | 200: 144 | description: Message received and processed. 145 | 500: 146 | description: Unexpected error 147 | content: 148 | application/json: 149 | schema: 150 | $ref: '#/components/schemas/Error' 151 | 152 | get: 153 | summary: Get all subscriptions 154 | operationId: listSubscription 155 | security: 156 | - BearerAuth: [notif.sub.read] 157 | tags: 158 | - Subscriber 159 | responses: 160 | 200: 161 | description: Get all subscriptions 162 | content: 163 | application/json: 164 | schema: 165 | type: array 166 | items: 167 | $ref: '#/components/schemas/Subscription' 168 | 500: 169 | description: Unexpected error 170 | content: 171 | application/json: 172 | schema: 173 | $ref: '#/components/schemas/Error' 174 | 175 | 176 | /v1/subscriptions/{uuid}: 177 | delete: 178 | summary: Unsubscribe from a topic 179 | description: Unsubscribes a client from receiving notifications for a topic 180 | operationId: unsubscribe 181 | security: 182 | - BearerAuth: [notif.sub.write] 183 | tags: 184 | - Subscriber 185 | parameters: 186 | - name: uuid 187 | in: path 188 | required: true 189 | description: the unique ID returned when the subscription was done 190 | schema: 191 | type: string 192 | responses: 193 | 204: 194 | description: Subscription successfully removed 195 | 400: 196 | description: Bad request 197 | content: 198 | application/json: 199 | schema: 200 | $ref: '#/components/schemas/Error' 201 | 404: 202 | description: Subscription not found 203 | 500: 204 | description: Unexpected error 205 | content: 206 | application/json: 207 | schema: 208 | $ref: '#/components/schemas/Error' 209 | 210 | /v1/subscriptions/confirm: 211 | get: 212 | summary: Confirm the subscription 213 | description: | 214 | Confirm a subscription 215 | operationId: confirm 216 | security: 217 | - BearerAuth: [notif.sub.write] 218 | tags: 219 | - Subscriber 220 | parameters: 221 | - name: token 222 | in: query 223 | required: true 224 | description: the token sent to the endpoint 225 | schema: 226 | type: string 227 | responses: 228 | 200: 229 | description: Subscription successfully confirmed 230 | 400: 231 | description: Bad request (invalid token) 232 | content: 233 | application/json: 234 | schema: 235 | $ref: '#/components/schemas/Error' 236 | 500: 237 | description: Unexpected error 238 | content: 239 | application/json: 240 | schema: 241 | $ref: '#/components/schemas/Error' 242 | 243 | 244 | /v1/topics: 245 | post: 246 | summary: Create a topic 247 | description: Create a new topic. This service is idempotent. 248 | operationId: createTopic 249 | security: 250 | - BearerAuth: [notif.topic.write] 251 | tags: 252 | - Publisher 253 | parameters: 254 | - name: name 255 | in: query 256 | required: true 257 | description: The topic name 258 | schema: 259 | type: string 260 | responses: 261 | 200: 262 | description: Topic was created. 263 | content: 264 | application/json: 265 | schema: 266 | $ref: '#/components/schemas/Topic' 267 | 400: 268 | description: Bad request 269 | content: 270 | application/json: 271 | schema: 272 | $ref: '#/components/schemas/Error' 273 | 500: 274 | description: Unexpected error 275 | content: 276 | application/json: 277 | schema: 278 | $ref: '#/components/schemas/Error' 279 | 280 | get: 281 | summary: Get all topics 282 | operationId: listTopics 283 | security: 284 | - BearerAuth: [notif.topic.read] 285 | tags: 286 | - Publisher 287 | responses: 288 | 200: 289 | description: Get all topics 290 | content: 291 | application/json: 292 | schema: 293 | type: array 294 | items: 295 | $ref: '#/components/schemas/Topic' 296 | 500: 297 | description: Unexpected error 298 | content: 299 | application/json: 300 | schema: 301 | $ref: '#/components/schemas/Error' 302 | 303 | /v1/topics/{uuid}: 304 | delete: 305 | summary: Delete a topic 306 | description: Delete a topic 307 | operationId: deleteTopic 308 | security: 309 | - BearerAuth: [notif.topic.write] 310 | tags: 311 | - Publisher 312 | parameters: 313 | - name: uuid 314 | in: path 315 | required: true 316 | description: the unique ID returned when the topic was created 317 | schema: 318 | type: string 319 | responses: 320 | 204: 321 | description: Topic successfully removed 322 | 400: 323 | description: Bad request 324 | content: 325 | application/json: 326 | schema: 327 | $ref: '#/components/schemas/Error' 328 | 404: 329 | description: Topic not found 330 | 500: 331 | description: Unexpected error 332 | content: 333 | application/json: 334 | schema: 335 | $ref: '#/components/schemas/Error' 336 | 337 | /v1/topics/{uuid}/publish: 338 | post: 339 | summary: Post a notification to a topic. 340 | operationId: publish 341 | security: 342 | - BearerAuth: [notif.topic.publish] 343 | tags: 344 | - Publisher 345 | parameters: 346 | - name: uuid 347 | in: path 348 | required: true 349 | description: the unique ID of the topic 350 | schema: 351 | type: string 352 | - name: subject 353 | in: query 354 | required: false 355 | description: the subject of the message. 356 | schema: 357 | type: string 358 | requestBody: 359 | description: Message posted 360 | required: true 361 | content: 362 | plain/text: 363 | schema: 364 | type: string 365 | responses: 366 | 200: 367 | description: Notification published 368 | 400: 369 | description: Bad request 370 | content: 371 | application/json: 372 | schema: 373 | $ref: '#/components/schemas/Error' 374 | 500: 375 | description: Unexpected error 376 | content: 377 | application/json: 378 | schema: 379 | $ref: '#/components/schemas/Error' 380 | 381 | components: 382 | securitySchemes: 383 | BearerAuth: 384 | type: http 385 | scheme: bearer 386 | bearerFormat: JWT 387 | schemas: 388 | Error: 389 | type: object 390 | required: 391 | - code 392 | - message 393 | properties: 394 | code: 395 | type: integer 396 | format: int32 397 | message: 398 | type: string 399 | additionalProperties: false 400 | Message: 401 | type: object 402 | required: 403 | - type 404 | - message 405 | properties: 406 | type: 407 | type: string 408 | enum: [SubscriptionConfirmation, Notification] 409 | token: 410 | type: string 411 | description: Confirmation token, also available in subscribeURL 412 | topic: 413 | type: string 414 | message: 415 | type: string 416 | messageId: 417 | type: string 418 | subject: 419 | type: string 420 | subscribeURL: 421 | type: string 422 | format: uri 423 | description: URL to visit to confirm the subscription to a topic 424 | timestamp: 425 | type: string 426 | format: date-time 427 | additionalProperties: false 428 | Topic: 429 | type: object 430 | properties: 431 | uuid: 432 | type: string 433 | description: The unique ID of the topic 434 | name: 435 | type: string 436 | additionalProperties: false 437 | Subscription: 438 | type: object 439 | properties: 440 | uuid: 441 | type: string 442 | description: The unique ID of the subscription 443 | topic: 444 | type: string 445 | description: Topic unique ID 446 | protocol: 447 | type: string 448 | enum: [http, email] 449 | address: 450 | type: string 451 | policy: 452 | type: string 453 | active: 454 | type: boolean 455 | description: Status indicating if the subscription was confirmed or not. 456 | additionalProperties: false 457 | 458 | -------------------------------------------------------------------------------- /src/doc/functional/_pr.rst: -------------------------------------------------------------------------------- 1 | 2 | Population Registry Services 3 | ---------------------------- 4 | 5 | This interface describes services to manage a registry of the population in the context of an identity system. It is based on 6 | the following principles: 7 | 8 | - It supports a history of identities, meaning that a person has one identity and this identity 9 | has a history. 10 | - Images can be passed by value or reference. When passed by value, they are base64-encoded. 11 | - Existing standards are used whenever possible. 12 | - This interface is complementary to the data access interface. The data access interface is used 13 | to query the persons and uses the reference identity to return attributes. 14 | - The population registry can store the biometric data or can rely on the ABIS subsystem to do it. 15 | The preferred solution, for a clean separation of data of different nature and by application 16 | of GDPR principles, is to put the biometric data only in the ABIS. Yet many existing systems 17 | store biometric data with the biographic data and this specification gives the flexibility to do it. 18 | 19 | See :ref:`annex-interface-pr` for the technical details of this interface. 20 | 21 | Services 22 | """""""" 23 | 24 | .. py:function:: findPersons(expressions, group, reference, gallery, offset, limit, transactionID) 25 | :noindex: 26 | 27 | Retrieve a list of persons which match passed in search criteria. 28 | 29 | **Authorization**: ``pr.person.read`` 30 | 31 | :param list[(str,str,str)] expressions: The expressions to evaluate. Each expression is described with the attribute's name, the operator (one of ``<``, ``>``, ``=``, ``>=``, ``<=``) and the attribute value 32 | :param bool group: Group the results per person and return only personID 33 | :param bool reference: Limit the query to the reference identities 34 | :param string gallery: A gallery ID used to limit the search 35 | :param int offset: The offset of the query (first item of the response) (optional, default to ``0``) 36 | :param int limit: The maximum number of items to return (optional, default to ``100``) 37 | :param string transactionID: The client generated transactionID. 38 | :return: a status indicating success or error and in case of success the matching person list. 39 | 40 | .. py:function:: createPerson(personID, personData, transactionID) 41 | :noindex: 42 | 43 | Create a new person. 44 | 45 | **Authorization**: ``pr.person.write`` 46 | 47 | :param str personID: The ID of the person. If the person already exists for the ID an error is returned. 48 | :param personData: The person attributes. 49 | :param str transactionID: A free text used to track the system activities related to the same transaction. 50 | :return: a status indicating success or error. 51 | 52 | .. py:function:: readPerson(personID, transactionID) 53 | :noindex: 54 | 55 | Read the attributes of a person. 56 | 57 | **Authorization**: ``pr.person.read`` 58 | 59 | :param str personID: The ID of the person. 60 | :param str transactionID: A free text used to track the system activities related to the same transaction. 61 | :return: a status indicating success or error and in case of success the person data. 62 | 63 | .. py:function:: updatePerson(personID, personData, transactionID) 64 | :noindex: 65 | 66 | Update a person. 67 | 68 | **Authorization**: ``pr.person.write`` 69 | 70 | :param str personID: The ID of the person. 71 | :param dict personData: The person data. 72 | :return: a status indicating success or error. 73 | 74 | .. py:function:: deletePerson(personID, transactionID) 75 | :noindex: 76 | 77 | Delete a person and all its identities. 78 | 79 | **Authorization**: ``pr.person.write`` 80 | 81 | :param str personID: The ID of the person. 82 | :param str transactionID: A free text used to track the system activities related to the same transaction. 83 | :return: a status indicating success or error. 84 | 85 | .. py:function:: mergePerson(personID1, personID2, transactionID) 86 | :noindex: 87 | 88 | Merge two person records into a single one. Identity ID are preserved and in case of duplicates 89 | an error is returned and no changes are done. 90 | The reference identity is not changed. 91 | 92 | **Authorization**: ``pr.person.write`` 93 | 94 | :param str personID1: The ID of the person that will receive new identities 95 | :param str personID2: The ID of the person that will give its identities. It will be deleted if the move of all identities is successful. 96 | :param str transactionID: A free text used to track the system activities related to the same transaction. 97 | :return: a status indicating success or error. 98 | 99 | ---------- 100 | 101 | .. py:function:: createIdentity(personID, identityID, identity, transactionID) 102 | :noindex: 103 | 104 | Create a new identity in a person. If no identityID is provided, a new one is generated. If identityID 105 | is provided, it is checked for uniqueness and used for the identity if unique. 106 | An error is returned if the provided identityID is not unique. 107 | 108 | **Authorization**: ``pr.identity.write`` 109 | 110 | :param str personID: The ID of the person. 111 | :param str identityID: The ID of the identity. 112 | :param identity: The new identity data. 113 | :param str transactionID: A free text used to track the system activities related to the same transaction. 114 | :return: a status indicating success or error. 115 | 116 | .. py:function:: readIdentity(personID, identityID, transactionID) 117 | :noindex: 118 | 119 | Read one or all the identities of one person. 120 | 121 | **Authorization**: ``pr.identity.read`` 122 | 123 | :param str personID: The ID of the person. 124 | :param str identityID: The ID of the identity. If not provided, all identities are returned. 125 | :param str transactionID: A free text used to track the system activities related to the same transaction. 126 | :return: a status indicating success or error, and in case of success a list of identities. 127 | 128 | .. py:function:: updateIdentity(personID, identityID, identity, transactionID) 129 | :noindex: 130 | 131 | Update an identity. An identity can be updated only in the status ``claimed``. 132 | 133 | **Authorization**: ``pr.identity.write`` 134 | 135 | :param str personID: The ID of the person. 136 | :param str identityID: The ID of the identity. 137 | :param identity: The identity data. 138 | :param str transactionID: A free text used to track the system activities related to the same transaction. 139 | :return: a status indicating success or error. 140 | 141 | .. py:function:: partialUpdateIdentity(personID, identityID, identity, transactionID) 142 | :noindex: 143 | 144 | Update part of an identity. Not all attributes are mandatory. The payload 145 | is defined as per :rfc:`7396`. 146 | An identity can be updated only in the status ``claimed``. 147 | 148 | **Authorization**: ``pr.identity.write`` 149 | 150 | :param str personID: The ID of the person. 151 | :param str identityID: The ID of the identity. 152 | :param identity: Part of the identity data. 153 | :return: a status indicating success or error. 154 | 155 | .. py:function:: deleteIdentity(personID, identityID, transactionID) 156 | :noindex: 157 | 158 | Delete an identity. 159 | 160 | **Authorization**: ``pr.identity.write`` 161 | 162 | :param str personID: The ID of the person. 163 | :param str identityID: The ID of the identity. 164 | :param str transactionID: A free text used to track the system activities related to the same transaction. 165 | :return: a status indicating success or error. 166 | 167 | .. py:function:: setIdentityStatus(personID, identityID, status, transactionID) 168 | :noindex: 169 | 170 | Set an identity status. 171 | 172 | **Authorization**: ``pr.identity.write`` 173 | 174 | :param str personID: The ID of the person. 175 | :param str identityID: The ID of the identity. 176 | :param str status: The new status of the identity. 177 | :param str transactionID: A free text used to track the system activities related to the same transaction. 178 | :return: a status indicating success or error. 179 | 180 | ---------- 181 | 182 | .. py:function:: defineReference(personID, identityID, transactionID) 183 | :noindex: 184 | 185 | Define the reference identity of one person. 186 | 187 | **Authorization**: ``pr.reference.write`` 188 | 189 | :param str personID: The ID of the person. 190 | :param str identityID: The ID of the identity being now the reference. 191 | :param str transactionID: A free text used to track the system activities related to the same transaction. 192 | :return: a status indicating success or error. 193 | 194 | .. py:function:: readReference(personID, transactionID) 195 | :noindex: 196 | 197 | Read the reference identity of one person. 198 | 199 | **Authorization**: ``pr.reference.read`` 200 | 201 | :param str personID: The ID of the person. 202 | :param str transactionID: A free text used to track the system activities related to the same transaction. 203 | :return: a status indicating success or error and in case of success the reference identity. 204 | 205 | ---------- 206 | 207 | .. py:function:: readGalleries(transactionID) 208 | :noindex: 209 | 210 | Read the ID of all the galleries. 211 | 212 | **Authorization**: ``pr.gallery.read`` 213 | 214 | :param str transactionID: A free text used to track the system activities related to the same transaction. 215 | :return: a status indicating success or error, and in case of success a list of gallery ID. 216 | 217 | .. py:function:: readGalleryContent(galleryID, transactionID, offset, limit) 218 | :noindex: 219 | 220 | Read the content of one gallery, i.e. the IDs of all the records linked to this gallery. 221 | 222 | **Authorization**: ``pr.gallery.read`` 223 | 224 | :param str galleryID: Gallery whose content will be returned. 225 | :param str transactionID: A free text used to track the system activities related to the same transaction. 226 | :param int offset: The offset of the query (first item of the response) (optional, default to ``0``) 227 | :param int limit: The maximum number of items to return (optional, default to ``1000``) 228 | :return: a status indicating success or error. In case of success a list of person/identity IDs. 229 | 230 | 231 | Data Model 232 | """""""""" 233 | 234 | 235 | .. list-table:: Population Registry Data Model 236 | :header-rows: 1 237 | :widths: 25 50 25 238 | 239 | * - Type 240 | - Description 241 | - Example 242 | 243 | * - Gallery 244 | - A group of persons related by a common purpose, designation, or status. 245 | A person can belong to multiple galleries. 246 | - ``VIP``, ``Wanted``, etc. 247 | 248 | * - Person 249 | - Person who is known to an identity assurance system. A person record has: 250 | 251 | - a status, such as ``active`` or ``inactive``, defining the status of the record 252 | (the record can be excluded from queries based on this status), 253 | - a physical status, such as ``alive`` or ``dead``, defining the status of the person, 254 | - a set of identities, keeping track of all identity data submitted by the person during 255 | the life of the system, 256 | - a reference identity, i.e. a consolidated view of all the identities 257 | defining the current correct identity of the person. It corresponds usually to the last 258 | valid identity but it can also include data from previous identities. 259 | - N/A 260 | 261 | * - Identity 262 | - The attributes describing an identity of a person. 263 | An identity has a status such as: ``claimed`` (identity not yet validated), ``valid`` 264 | (the identity is valid), ``invalid`` (the identity is confirmed as not valid), ``revoked`` (the identity 265 | cannot be used any longer). 266 | 267 | An identity can be updated only in the status ``claimed``. 268 | 269 | The proposed transitions for the status are represented below. It can be adapted if needed. 270 | 271 | .. uml:: 272 | :scale: 30% 273 | 274 | [*] --> claimed 275 | claimed --> valid 276 | claimed -->invalid 277 | valid --> revoked 278 | valid -> invalid 279 | 280 | The attributes are separated into two categories: the biographic data and the contextual data. 281 | 282 | - N/A 283 | 284 | * - Biographic Data 285 | - A dictionary (list of names and values) giving the biographic data of the identity 286 | - ``firstName``, ``lastName``, ``dateOfBirth``, etc. 287 | 288 | * - Contextual Data 289 | - A dictionary (list of names and values) attached to the context of establishing the identity 290 | - ``operatorName``, ``enrollmentDate``, etc. 291 | 292 | * - Biometric Data 293 | - Digital representation of biometric characteristics. 294 | 295 | All images can be passed by value (image buffer is in the request) or by reference (the address of the 296 | image is in the request). 297 | Biometric images can be compliant with ISO 19794 or ISO 39794, which allow multiple encoding and supports additional 298 | metadata specific to fingerprint, palmprint, portrait, iris or signature. 299 | 300 | A biometric data can be associated to no image or a partial image if it includes information about 301 | the missing items (example: one finger may be amputated on a 4 finger image) 302 | - fingerprint, portrait, iris, signature 303 | 304 | * - Document 305 | - The document data (images) attached to the identity and used to validate it. 306 | - Birth certificate, invoice 307 | 308 | .. uml:: 309 | :caption: Population Registry Data Model 310 | :scale: 50% 311 | 312 | class Gallery { 313 | string galleryID; 314 | } 315 | 316 | class Person { 317 | string personID; 318 | enum status: Active | Inactive; 319 | enum physicalStatus: Alive | Dead; 320 | } 321 | 322 | class Identity { 323 | string identityID; 324 | enum status: Claimed | Valid | Invalid | Revoked; 325 | byte[] clientData; 326 | } 327 | 328 | Gallery "*" -- "*" Identity 329 | 330 | Person -- "*" Identity: "identities" 331 | Person -- Identity: "reference" 332 | 333 | class BiographicData { 334 | string firstName; 335 | string lastName; 336 | date dateOfBirth; 337 | date dateOfDeath; 338 | string addressLine1; 339 | ... 340 | } 341 | Identity o- BiographicData 342 | 343 | class ContextualData { 344 | string field1; 345 | int field2; 346 | date field3; 347 | ... 348 | } 349 | ContextualData -o Identity 350 | 351 | class BiometricData { 352 | string type 353 | string subType 354 | byte[] image 355 | URL imageRef 356 | ... 357 | } 358 | Identity "1" -- "0..*" BiometricData 359 | 360 | class Document { 361 | enum type: Doc1 | Doc2 | Signature | etc; 362 | string instance; 363 | } 364 | 365 | class DocumentPart { 366 | int[] pages; 367 | byte[] data; 368 | URL dataRef; 369 | int width; 370 | int height; 371 | date captureDate; 372 | string captureDevice; 373 | string format; 374 | } 375 | 376 | Identity "1" -- "0..*" Document 377 | 378 | Document "1" -- "1..*" DocumentPart 379 | -------------------------------------------------------------------------------- /src/doc/yaml/dataaccess.yaml: -------------------------------------------------------------------------------- 1 | 2 | # (c) Secure Identity Alliance 3 | 4 | openapi: 3.0.0 5 | info: 6 | description: | 7 | The OSIA Data Access Interface. 8 | 9 | Change log: 10 | 11 | - 1.3.0: 12 | - Add errors 400 and return error details 13 | - Force additionalProperties to false when extension is not allowed 14 | - Add pagination for query service. limit parameter replaces the max parameter. 15 | - 1.2.0: addition of security 16 | - 1.1.0: extended queryPersonUIN/queryPersonList operation to return a list of attributes, and not only a list of UIN 17 | - 1.0.0: first version proposed in OSIA. 18 | 19 | version: 1.3.0 20 | title: OSIA Data Access Interface 21 | license: 22 | name: SIA 23 | url: "https://raw.githubusercontent.com/SecureIdentityAlliance/osia/master/LICENSE" 24 | servers: 25 | - url: https://pr.com/ 26 | - url: https://cr.com/ 27 | tags: 28 | - name: Person 29 | - name: Document 30 | paths: 31 | /v1/persons: 32 | get: 33 | description: | 34 | Query for persons using a set of attributes. Retrieve the UIN or the person attributes. 35 | This service is used when the UIN is unknown. 36 | Example: http://registry.com/v1/persons?firstName=John&lastName=Do&names=firstName 37 | operationId: queryPersonList 38 | security: 39 | - BearerAuth: [pr.person.read, cr.person.read] 40 | tags: 41 | - Person 42 | parameters: 43 | - name: attributes 44 | in: query 45 | description: The attributes (names and values) used to query 46 | required: true 47 | schema: 48 | type: object 49 | additionalProperties: true 50 | style: form 51 | explode: true 52 | example: 53 | firstName: John 54 | lastName: Do 55 | - name: names 56 | in: query 57 | description: The names of the attributes to return. If not provided, only the UIN is returned 58 | required: false 59 | schema: 60 | type: array 61 | items: 62 | type: string 63 | style: form 64 | explode: true 65 | example: 66 | - firstName 67 | - lastName 68 | - name: offset 69 | in: query 70 | description: The offset of the query (first item of the response) 71 | required: false 72 | schema: 73 | type: integer 74 | default: 0 75 | - name: limit 76 | in: query 77 | description: The maximum number of items to return 78 | required: false 79 | schema: 80 | type: integer 81 | default: 100 82 | 83 | responses: 84 | 200: 85 | description: > 86 | The requested attributes for all found persons (a list of at least one entry). 87 | 88 | If no names are given, a flat list of UIN is returned. 89 | If at least one name is given, a list of dictionaries (one dictionary per record) is returned. 90 | content: 91 | application/json: 92 | schema: 93 | oneOf: 94 | - type: array 95 | minimum: 1 96 | items: 97 | type: string 98 | example: 99 | - "1235567890" 100 | - type: array 101 | minimum: 1 102 | items: 103 | type: object 104 | additionalProperties: 105 | oneOf: 106 | - type: string 107 | - type: integer 108 | - type: number 109 | - type: boolean 110 | - $ref: '#/components/schemas/Error' 111 | example: 112 | firstName: John 113 | lastName: Doo 114 | dob: 115 | code: 1023 116 | message: Unknown attribute name 117 | 118 | 400: 119 | description: Invalid parameter 120 | content: 121 | application/json: 122 | schema: 123 | $ref: '#/components/schemas/Error' 124 | 401: 125 | description: Client must be authenticated 126 | 403: 127 | description: Service forbidden 128 | 404: 129 | description: No record found 130 | 500: 131 | description: Unexpected error 132 | content: 133 | application/json: 134 | schema: 135 | $ref: '#/components/schemas/Error' 136 | 137 | /v1/persons/{uin}: 138 | get: 139 | description: "Read attributes for a person. Example: http://registry.com/v1/persons/123456789?attributeNames=firstName&attributeNames=lastName&attributeNames=dob" 140 | operationId: readPersonAttributes 141 | security: 142 | - BearerAuth: [pr.person.read, cr.person.read] 143 | tags: 144 | - Person 145 | parameters: 146 | - name: uin 147 | in: path 148 | description: Unique Identity Number 149 | required: true 150 | schema: 151 | type: string 152 | - name: attributeNames 153 | in: query 154 | description: The names of the attributes requested for this person 155 | required: true 156 | schema: 157 | type: array 158 | items: 159 | type: string 160 | example: 161 | - firstName 162 | - lastName 163 | - dob 164 | responses: 165 | 200: 166 | description: Requested attributes values or error description. 167 | content: 168 | application/json: 169 | schema: 170 | type: object 171 | additionalProperties: 172 | oneOf: 173 | - type: string 174 | - type: integer 175 | - type: number 176 | - type: boolean 177 | - $ref: '#/components/schemas/Error' 178 | example: 179 | firstName: John 180 | lastName: Doo 181 | dob: 182 | code: 1023 183 | message: Unknown attribute name 184 | 400: 185 | description: Invalid parameter 186 | content: 187 | application/json: 188 | schema: 189 | $ref: '#/components/schemas/Error' 190 | 401: 191 | description: Client must be authenticated 192 | 403: 193 | description: Service forbidden 194 | 404: 195 | description: Unknown uin 196 | 500: 197 | description: Unexpected error 198 | content: 199 | application/json: 200 | schema: 201 | $ref: '#/components/schemas/Error' 202 | 203 | /v1/persons/{uin}/match: 204 | post: 205 | description: | 206 | Match person attributes. 207 | This service is used to check the value of attributes without exposing private data. 208 | 209 | The request body should contain a list of attributes and their value, formatted as a json dictionary. 210 | operationId: matchPersonAttributes 211 | security: 212 | - BearerAuth: [pr.person.match, cr.person.match] 213 | tags: 214 | - Person 215 | parameters: 216 | - name: uin 217 | in: path 218 | description: Unique Identity Number 219 | required: true 220 | schema: 221 | type: string 222 | requestBody: 223 | description: A set of attributes for the person 224 | content: 225 | application/json: 226 | schema: 227 | $ref: '#/components/schemas/Attributes' 228 | example: 229 | firstName: John 230 | lastName: Doo 231 | dateOfBirth: "1984-11-19" 232 | responses: 233 | 200: 234 | description: | 235 | Information about non matching attributes. Returns a list of matching result. 236 | An empty list indicates all attributes were matching. 237 | content: 238 | application/json: 239 | schema: 240 | $ref: '#/components/schemas/MatchingError' 241 | example: 242 | - attributeName: firstName 243 | errorCode: 1 244 | 400: 245 | description: Invalid parameter 246 | content: 247 | application/json: 248 | schema: 249 | $ref: '#/components/schemas/Error' 250 | 401: 251 | description: Client must be authenticated 252 | 403: 253 | description: Service forbidden 254 | 404: 255 | description: Unknown uin 256 | 500: 257 | description: Unexpected error 258 | content: 259 | application/json: 260 | schema: 261 | $ref: '#/components/schemas/Error' 262 | 263 | /v1/persons/{uin}/verify: 264 | post: 265 | description: | 266 | Evaluate expressions on person attributes. 267 | This service is used to evaluate simple expressions on 268 | person's attributes without exposing private data 269 | 270 | The request body should contain a list of expressions. 271 | operationId: verifyPersonAttributes 272 | security: 273 | - BearerAuth: [pr.person.verify, cr.person.verify] 274 | tags: 275 | - Person 276 | parameters: 277 | - name: uin 278 | in: path 279 | description: Unique Identity Number 280 | required: true 281 | schema: 282 | type: string 283 | requestBody: 284 | description: A set of expressions on attributes of the person 285 | content: 286 | application/json: 287 | schema: 288 | $ref: '#/components/schemas/Expressions' 289 | example: 290 | - attributeName: firstName 291 | operator: "=" 292 | value: John 293 | - attributeName: dateOfBirth 294 | operator: "<" 295 | value: "1990-12-31" 296 | responses: 297 | 200: 298 | description: The expressions are all true (true is returned) or one is false (false is returned) 299 | content: 300 | application/json: 301 | schema: 302 | type: boolean 303 | example: 304 | true 305 | 400: 306 | description: Invalid parameter 307 | content: 308 | application/json: 309 | schema: 310 | $ref: '#/components/schemas/Error' 311 | 401: 312 | description: Client must be authenticated 313 | 403: 314 | description: Forbidden access. The service is forbidden or one of the attributes is forbidden. 315 | 404: 316 | description: Unknown uin 317 | 500: 318 | description: Unexpected error 319 | content: 320 | application/json: 321 | schema: 322 | $ref: '#/components/schemas/Error' 323 | 324 | /v1/persons/{uin}/document: 325 | get: 326 | description: | 327 | Read in an unstructured format (PDF, image) a document such as a marriage certificate. 328 | Example: ``http://registry.com/v1/persons/123456789/document?doctype=marriage&secondaryUin=234567890&format=pdf`` 329 | operationId: readDocument 330 | security: 331 | - BearerAuth: [pr.document.read, cr.document.read] 332 | tags: 333 | - Document 334 | parameters: 335 | - name: uin 336 | in: path 337 | description: Unique Identity Number 338 | required: true 339 | schema: 340 | type: string 341 | - name: secondaryUin 342 | in: query 343 | description: | 344 | Unique Identity Number of a second person linked to the requested document. 345 | Example: wife, husband 346 | required: false 347 | schema: 348 | type: string 349 | - name: doctype 350 | in: query 351 | description: The type of document 352 | required: true 353 | schema: 354 | type: string 355 | - name: format 356 | in: query 357 | description: | 358 | The expected format of the document. 359 | If the document is not available at this format, it must be converted. 360 | TBD: one format for certificate data. 361 | required: true 362 | schema: 363 | type: string 364 | enum: ['pdf', 'jpeg', 'png', 'TBD'] 365 | responses: 366 | 200: 367 | description: The document(s) is/are found and returned, as binary data in a MIME multipart structure. 368 | content: 369 | multipart/mixed: 370 | schema: 371 | type: object 372 | properties: 373 | documents: 374 | type: array 375 | items: 376 | type: string 377 | format: binary 378 | additionalProperties: false 379 | encoding: 380 | documents: 381 | contentType: application/pdf, image/jpeg, image/png 382 | 400: 383 | description: Invalid parameter 384 | content: 385 | application/json: 386 | schema: 387 | $ref: '#/components/schemas/Error' 388 | 401: 389 | description: Client must be authenticated 390 | 403: 391 | description: Service forbidden 392 | 404: 393 | description: Unknown uin 394 | 415: 395 | description: Unsupported format 396 | 500: 397 | description: Unexpected error 398 | content: 399 | application/json: 400 | schema: 401 | $ref: '#/components/schemas/Error' 402 | 403 | components: 404 | securitySchemes: 405 | BearerAuth: 406 | type: http 407 | scheme: bearer 408 | bearerFormat: JWT 409 | schemas: 410 | Error: 411 | type: object 412 | required: 413 | - code 414 | - message 415 | properties: 416 | code: 417 | type: integer 418 | format: int32 419 | message: 420 | type: string 421 | additionalProperties: false 422 | Attributes: 423 | type: object 424 | additionalProperties: 425 | oneOf: 426 | - type: string 427 | - type: integer 428 | - type: number 429 | - type: boolean 430 | # Or ?: 431 | #additionalProperties: true 432 | Expression: 433 | type: object 434 | required: 435 | - attributeName 436 | - operator 437 | - value 438 | properties: 439 | attributeName: 440 | type: string 441 | operator: 442 | type: string 443 | enum: ['<', '>', '=', '>=', '<='] 444 | value: 445 | oneOf: 446 | - type: string 447 | - type: integer 448 | - type: number 449 | - type: boolean 450 | additionalProperties: false 451 | Expressions: 452 | type: array 453 | items: 454 | $ref: '#/components/schemas/Expression' 455 | MatchingError: 456 | type: array 457 | items: 458 | type: object 459 | properties: 460 | attributeName: 461 | type: string 462 | errorCode: 463 | type: integer 464 | format: int32 465 | enum: [0, 1] 466 | description: 0=attribute does not exist; 1=attribute exists but does not match 467 | additionalProperties: false 468 | 469 | -------------------------------------------------------------------------------- /src/doc/functional/_abis.rst: -------------------------------------------------------------------------------- 1 | 2 | Biometrics 3 | ---------- 4 | 5 | This interface describes biometric services in the context of an identity system. It is based on 6 | the following principles: 7 | 8 | - It supports only multi-encounter model, meaning that an identity can have multiple set of biometric data, 9 | one for each encounter. 10 | - It does not expose templates (only images) for CRUD services, with one exception to support 11 | the use case of credentials with biometrics. 12 | - Images can be passed by value or reference. When passed by value, they are base64-encoded. 13 | - Existing standards are used whenever possible. 14 | 15 | .. admonition:: About synchronous and asynchronous processing 16 | 17 | Some services can be very slow depending on the algorithm used, the system workload, etc. 18 | Services are described so that: 19 | 20 | - If possible, the answer is provided synchronously in the response of the service. 21 | - If not possible for some reason, a status *PENDING* is returned and the answer, when available, is 22 | pushed to a callback provided by the client. 23 | 24 | If no callback is provided, this indicates that the client wants a synchronous answer, whatever the time it takes. 25 | 26 | If a callback is provided, this indicates that the client wants an asynchronous answer, even if the result is immediately available. 27 | 28 | See :ref:`annex-interface-abis` for the technical details of this interface. 29 | 30 | Services 31 | """""""" 32 | 33 | .. py:function:: createEncounter(personID, encounterID, galleryID, biographicData, contextualData, biometricData, clientData,callback, transactionID, options) 34 | :noindex: 35 | 36 | Create a new encounter. No identify is performed. 37 | 38 | **Authorization**: ``abis.encounter.write`` 39 | 40 | :param str personID: The person ID. This is optional and will be generated if not provided 41 | :param str encounterID: The encounter ID. This is optional and will be generated if not provided 42 | :param list(str) galleryID: the gallery ID to which this encounter belongs. A minimum of one gallery must be provided 43 | :param dict biographicData: The biographic data (ex: name, date of birth, gender, etc.) 44 | :param dict contextualData: The contextual data (ex: encounter date, location, etc.) 45 | :param list biometricData: the biometric data (images) 46 | :param bytes clientData: additional data not interpreted by the server but stored as is and returned 47 | when encounter data is requested. 48 | :param callback: The address of a service to be called when the result is available. 49 | :param str transactionID: A free text used to track the system activities related to the same transaction. 50 | :param dict options: the processing options. Supported options are ``priority``, ``algorithm``. 51 | :return: a status indicating success, error, or pending operation. 52 | In case of success, the person ID and the encounter ID are returned. 53 | In case of pending operation, the result will be sent later. 54 | 55 | .. py:function:: readEncounter(personID, encounterID, callback, transactionID, options) 56 | :noindex: 57 | 58 | Read the data of an encounter. 59 | 60 | **Authorization**: ``abis.encounter.read`` 61 | 62 | :param str personID: The person ID 63 | :param str encounterID: The encounter ID. This is optional. If not provided, all the 64 | encounters of the person are returned. 65 | :param callback: The address of a service to be called when the result is available. 66 | :param str transactionID: A free text used to track the system activities related to the same transaction. 67 | :param dict options: the processing options. Supported options are ``priority``. 68 | :return: a status indicating success, error, or pending operation. 69 | In case of success, the encounter data is returned. 70 | In case of pending operation, the result will be sent later. 71 | 72 | .. py:function:: updateEncounter(personID, encounterID, galleryID, biographicData, contextualData, biometricData, callback, transactionID, options) 73 | :noindex: 74 | 75 | Update an encounter. 76 | 77 | **Authorization**: ``abis.encounter.write`` 78 | 79 | :param str personID: The person ID 80 | :param str encounterID: The encounter ID 81 | :param list(str) galleryID: the gallery ID to which this encounter belongs. A minimum of one gallery must be provided 82 | :param dict biographicData: The biographic data (ex: name, date of birth, gender, etc.) 83 | :param dict contextualData: The contextual data (ex: encounter date, location, etc.) 84 | :param list biometricData: the biometric data (images) 85 | :param bytes clientData: additional data not interpreted by the server but stored as is and returned 86 | when encounter data is requested. 87 | :param callback: The address of a service to be called when the result is available. 88 | :param str transactionID: A free text used to track the system activities related to the same transaction. 89 | :param dict options: the processing options. Supported options are ``priority``, ``algorithm``. 90 | :return: a status indicating success, error, or pending operation. 91 | In case of success, the person ID and the encounter ID are returned. 92 | In case of pending operation, the result will be sent later. 93 | 94 | .. py:function:: deleteEncounter(personID, encounterID, callback, transactionID, options) 95 | :noindex: 96 | 97 | Delete an encounter. 98 | 99 | **Authorization**: ``abis.encounter.write`` 100 | 101 | :param str personID: The person ID 102 | :param str encounterID: The encounter ID. This is optional. If not provided, all the 103 | encounters of the person are deleted. 104 | :param callback: The address of a service to be called when the result is available. 105 | :param str transactionID: A free text used to track the system activities related to the same transaction. 106 | :param dict options: the processing options. Supported options are ``priority``. 107 | :return: a status indicating success, error, or pending operation. 108 | In case of pending operation, the operation status will be sent later. 109 | 110 | .. py:function:: mergeEncounter(personID1, personID2, callback, transactionID, options) 111 | :noindex: 112 | 113 | Merge two sets of encounters into a single set. Merging a set of *N* encounters with a set of *M* encounters 114 | will result in a single set of *N+M* encounters. Encounter ID are preserved and in case of duplicates 115 | an error is returned and no changes are done. 116 | 117 | **Authorization**: ``abis.encounter.write`` 118 | 119 | :param str personID1: The ID of the person that will receive new encounters 120 | :param str personID2: The ID of the person that will give its encounters 121 | :param callback: The address of a service to be called when the result is available. 122 | :param str transactionID: A free text used to track the system activities related to the same transaction. 123 | :param dict options: the processing options. Supported options are ``priority``. 124 | :return: a status indicating success, error, or pending operation. 125 | In case of pending operation, the result will be sent later. 126 | 127 | .. py:function:: moveEncounter(personID1, personID2, encounterID, callback, transactionID, options) 128 | :noindex: 129 | 130 | Move one single encounter from one person to another person. 131 | Encounter ID is preserved and in case of duplicates 132 | an error is returned and no changes are done. 133 | 134 | **Authorization**: ``abis.encounter.write`` 135 | 136 | :param str personID1: The ID of the person that will receive the encounter 137 | :param str personID2: The ID of the person that will give one encounter 138 | :param str encounterID: the ID of the encounter in personID2 that will be moved in personID1. 139 | :param callback: The address of a service to be called when the result is available. 140 | :param str transactionID: A free text used to track the system activities related to the same transaction. 141 | :param dict options: the processing options. Supported options are ``priority``. 142 | :return: a status indicating success, error, or pending operation. 143 | In case of pending operation, the result will be sent later. 144 | 145 | .. py:function:: readTemplate(personID, encounterID, biometricType, biometricSubType, templateFormat, qualityFormat, callback, transactionID, options) 146 | :noindex: 147 | 148 | Read the generated template. 149 | 150 | **Authorization**: ``abis.encounter.read`` 151 | 152 | :param str personID: The person ID 153 | :param str encounterID: The encounter ID. 154 | :param str biometricType: The type of biometrics to consider (optional) 155 | :param str biometricSubType: The subtype of biometrics to consider (optional) 156 | :param str templateFormat: the format of the template to return (optional) 157 | :param str qualityFormat: the format of the quality to return (optional) 158 | :param callback: The address of a service to be called when the result is available. 159 | :param str transactionID: A free text used to track the system activities related to the same transaction. 160 | :param dict options: the processing options. Supported options are ``priority``. 161 | :return: a status indicating success, error, or pending operation. 162 | In case of success, a list of template data is returned. 163 | In case of pending operation, the result will be sent later. 164 | 165 | .. py:function:: updateEncounterStatus(personID, encounterID, status, transactionID) 166 | :noindex: 167 | 168 | Set an encounter status. 169 | 170 | **Authorization**: ``abis.encounter.write`` 171 | 172 | :param str personID: The ID of the person. 173 | :param str encounterID: The encounter ID. 174 | :param str status: The new status of the encounter. 175 | :param str transactionID: A free text used to track the system activities related to the same transaction. 176 | :return: a status indicating success or error. 177 | 178 | .. py:function:: updateEncounterGalleries(personID, encounterID, galleries, transactionID) 179 | :noindex: 180 | 181 | Update the galleries of an encounter. 182 | This service is used to move one encounter from one gallery 183 | to another one without updating the full encounter, which maybe 184 | resource consuming in a biometric system. 185 | 186 | **Authorization**: ``abis.encounter.write`` 187 | 188 | :param str personID: The ID of the person. 189 | :param str encounterID: The encounter ID. 190 | :param list[str] galleries: The new list of galleries for this encounter. 191 | :param str transactionID: A free text used to track the system activities related to the same transaction. 192 | :return: a status indicating success or error. 193 | 194 | ---------- 195 | 196 | .. py:function:: readGalleries(callback, transactionID, options) 197 | :noindex: 198 | 199 | Read the ID of all the galleries. 200 | 201 | **Authorization**: ``abis.gallery.read`` 202 | 203 | :param callback: The address of a service to be called when the result is available. 204 | :param str transactionID: A free text used to track the system activities related to the same transaction. 205 | :param dict options: the processing options. Supported options are ``priority``. 206 | :return: a status indicating success, error, or pending operation. 207 | A list of gallery ID is returned, either synchronously or using the callback. 208 | 209 | .. py:function:: readGalleryContent(galleryID, callback, transactionID, offset, limit, options) 210 | :noindex: 211 | 212 | Read the content of one gallery, i.e. the IDs of all the records linked to this gallery. 213 | 214 | **Authorization**: ``abis.gallery.read`` 215 | 216 | :param str galleryID: Gallery whose content will be returned. 217 | :param callback: The address of a service to be called when the result is available. 218 | :param str transactionID: A free text used to track the system activities related to the same transaction. 219 | :param int offset: The offset of the query (first item of the response) (optional, default to ``0``) 220 | :param int limit: The maximum number of items to return (optional, default to ``1000``) 221 | :param dict options: the processing options. Supported options are ``priority``. 222 | :return: a status indicating success, error, or pending operation. 223 | A list of persons/encounters is returned, either synchronously or using the callback. 224 | 225 | ---------- 226 | 227 | .. py:function:: identify(galleryID, filter, biometricData, callback, transactionID, options) 228 | :noindex: 229 | 230 | Identify a person using biometrics data and filters on biographic or contextual data. This may include multiple 231 | operations, including manual operations. 232 | 233 | **Authorization**: ``abis.identify`` 234 | 235 | :param str galleryID: Search only in this gallery. 236 | :param dict filter: The input data (filters and biometric data) 237 | :param biometricData: the biometric data. 238 | :param callback: The address of a service to be called when the result is available. 239 | :param str transactionID: A free text used to track the system activities related to the same transaction. 240 | :param dict options: the processing options. Supported options are ``priority``, 241 | ``maxNbCand``, ``threshold``, ``accuracyLevel``, ``serviceLevel``. 242 | :return: a status indicating success, error, or pending operation. 243 | A list of candidates is returned, either synchronously or using the callback. 244 | 245 | .. py:function:: identify(galleryID, filter, personID, callback, transactionID, options) 246 | :noindex: 247 | 248 | Identify a person using biometrics data of a person existing in the system and filters on biographic or 249 | contextual data. This may include multiple operations, including manual operations. 250 | 251 | **Authorization**: ``abis.identify`` 252 | 253 | :param str galleryID: Search only in this gallery. 254 | :param dict filter: The input data (filters and biometric data) 255 | :param personID: the person ID 256 | :param callback: The address of a service to be called when the result is available. 257 | :param str transactionID: A free text used to track the system activities related to the same transaction. 258 | :param dict options: the processing options. Supported options are ``priority``, 259 | ``maxNbCand``, ``threshold``, ``accuracyLevel``, ``serviceLevel``. 260 | :return: a status indicating success, error, or pending operation. 261 | A list of candidates is returned, either synchronously or using the callback. 262 | 263 | .. py:function:: identify(galleryID, filter, personID, encounterID, callback, transactionID, options) 264 | :noindex: 265 | 266 | Identify a person using biometrics data of an encounter existing in the system and filters on biographic or 267 | contextual data. This may include multiple operations, including manual operations. 268 | 269 | **Authorization**: ``abis.identify`` 270 | 271 | :param str galleryID: Search only in this gallery. 272 | :param dict filter: The input data (filters and biometric data) 273 | :param personID: the person ID 274 | :param encounterID: the encounter ID 275 | :param callback: The address of a service to be called when the result is available. 276 | :param str transactionID: A free text used to track the system activities related to the same transaction. 277 | :param dict options: the processing options. Supported options are ``priority``, 278 | ``maxNbCand``, ``threshold``, ``accuracyLevel``, ``serviceLevel``. 279 | :return: a status indicating success, error, or pending operation. 280 | A list of candidates is returned, either synchronously or using the callback. 281 | 282 | .. py:function:: verify(galleryID, personID, biometricData, callback, transactionID, options) 283 | :noindex: 284 | 285 | Verify an identity using biometrics data. 286 | 287 | **Authorization**: ``abis.verify`` 288 | 289 | :param str galleryID: Search only in this gallery. If the person does not belong to this gallery, 290 | an error is returned. 291 | :param str personID: The person ID 292 | :param biometricData: The biometric data 293 | :param callback: The address of a service to be called when the result is available. 294 | :param str transactionID: A free text used to track the system activities related to the same transaction. 295 | :param dict options: the processing options. Supported options are ``priority``, 296 | ``threshold``, ``accuracyLevel``, ``serviceLevel``. 297 | :return: a status indicating success, error, or pending operation. 298 | A status (boolean) is returned, either synchronously or using the callback. Optionally, details 299 | about the matching result can be provided like the score per biometric and per encounter. 300 | 301 | .. py:function:: verify(biometricData1, biometricData2, callback, transactionID, options) 302 | :noindex: 303 | 304 | Verify that two sets of biometrics data correspond to the same person. 305 | 306 | **Authorization**: ``abis.verify`` 307 | 308 | :param biometricData1: The first set of biometric data 309 | :param biometricData2: The second set of biometric data 310 | :param callback: The address of a service to be called when the result is available. 311 | :param str transactionID: A free text used to track the system activities related to the same transaction. 312 | :param dict options: the processing options. Supported options are ``priority``, 313 | ``threshold``, ``accuracyLevel``, ``serviceLevel``. 314 | :return: a status indicating success, error, or pending operation. 315 | A status (boolean) is returned, either synchronously or using the callback. Optionally, details 316 | about the matching result can be provided like the score per the biometric. 317 | 318 | ---------- 319 | 320 | .. py:function:: readTaskStatus(taskID, transactionID) 321 | :noindex: 322 | 323 | Read the execution status of an asynchronous service. 324 | 325 | **Authorization**: ``abis.task.read`` 326 | 327 | :param str taskID: the ID of the task. 328 | :param str transactionID: A free text used to track the system activities related to the same transaction. 329 | :return: a status indicating the status of the asynchronous task. 330 | 331 | .. py:function:: redeliverTaskResult(taskID, transactionID) 332 | :noindex: 333 | 334 | Trigger a new attempt to send a result by callback. 335 | 336 | **Authorization**: ``abis.task.read`` 337 | 338 | :param str taskID: the ID of the task. 339 | :param str transactionID: A free text used to track the system activities related to the same transaction. 340 | :return: a status indicating if a new attempt to call the callback will be made. 341 | 342 | Options 343 | """"""" 344 | 345 | .. list-table:: Biometric Services Options 346 | :header-rows: 1 347 | :widths: 25 75 348 | 349 | * - Name 350 | - Description 351 | 352 | * - ``priority`` 353 | - Priority of the request. Values range from ``0`` to ``9``. 354 | ``0`` indicates the lowest priority, ``9`` indicates the highest priority. 355 | * - ``maxNbCand`` 356 | - The maximum number of candidates to return. 357 | * - ``threshold`` 358 | - The threshold to apply on the score to filter the candidates during an identification, 359 | authentication or verification. 360 | * - ``algorithm`` 361 | - Specify the type of algorithm to be used. 362 | * - ``accuracyLevel`` 363 | - Specify the accuracy expected of the request. This is to support different use cases, when 364 | different behavior of the ABIS is expected (response time, accuracy, consolidation/fusion, etc.). 365 | * - ``serviceLevel`` 366 | - Specify the level of services expected, for example the response time. 367 | 368 | Data Model 369 | """""""""" 370 | 371 | .. list-table:: Biometric Data Model 372 | :header-rows: 1 373 | :widths: 25 50 25 374 | 375 | * - Type 376 | - Description 377 | - Example 378 | 379 | * - Gallery 380 | - A group of persons related by a common purpose, designation, or status. 381 | A person can belong to multiple galleries. 382 | - ``VIP``, ``Wanted``, etc. 383 | 384 | * - Person 385 | - Person who is known to an identity assurance system. 386 | - N/A 387 | 388 | * - Encounter 389 | - Event in which the client application interacts with a person resulting in data being 390 | collected during or about the encounter. An encounter is characterized by an *identifier* and a *type* 391 | (also called *purpose* in some context). 392 | 393 | An encounter has a status indicating if this encounter is used in the biometric searches. Allowed values 394 | are ``active`` or ``inactive``. 395 | 396 | - N/A 397 | 398 | * - Biographic Data 399 | - A dictionary (list of names and values) giving the biographic data of interest for the biometric services. 400 | This should be as limited as possible. 401 | - ``gender``, ``region``, ``yearOfBirth`` 402 | 403 | * - Filters 404 | - A dictionary (list of names and values or *range* of values) describing the filters during a search. 405 | Filters can apply on biographic data, contextual data or encounter type. 406 | - ``gender``, ``yearOfBirthMin``, ``yearOfBirthMax`` 407 | 408 | * - Biometric Data 409 | - Digital representation of biometric characteristics. 410 | 411 | All images can be passed by value (image buffer is in the request) or by reference (the address of the 412 | image is in the request). 413 | Biometric images can be compliant with ISO 19794 or ISO 39794, which allow multiple encoding and supports additional 414 | metadata specific to fingerprint, palmprint, portrait, iris or signature. 415 | 416 | A biometric data can be associated to no image or a partial image if it includes information about 417 | the missing items (example: one finger may be amputated on a 4 finger image) 418 | - fingerprint, portrait, iris, signature 419 | 420 | * - Candidate 421 | - Information about a candidate found during an identification 422 | - ``personId`` 423 | 424 | * - CandidateScore 425 | - Detailed information about a candidate found during an identification. It includes 426 | the score for the biometrics used. It can also be extended with proprietary information to better describe 427 | the matching result (for instance: rotation needed to align the probe and the candidate) 428 | - ``3000`` 429 | 430 | * - Template 431 | - A computed buffer corresponding to a biometric and allowing the comparison of biometrics. 432 | A template has a format that can be a standard format or a vendor-specific format. 433 | - N/A 434 | 435 | .. uml:: 436 | :caption: Biometric Data Model 437 | :scale: 50% 438 | 439 | class Gallery { 440 | string galleryID; 441 | } 442 | 443 | class Person { 444 | string personID; 445 | } 446 | 447 | class Encounter { 448 | string encounterID; 449 | string status; 450 | string encounterType; 451 | byte[] clientData; 452 | } 453 | 454 | Encounter "*" -- "*" Gallery 455 | 456 | Person o-- "*" Encounter 457 | 458 | class BiographicData { 459 | string field1; 460 | int field2; 461 | date field3; 462 | ... 463 | } 464 | Encounter o- BiographicData 465 | 466 | class ContextualData { 467 | string field1; 468 | int field2; 469 | date field3; 470 | ... 471 | } 472 | ContextualData -o Encounter 473 | 474 | class Filters { 475 | string filter1; 476 | int filter2Min; 477 | int filter2Max; 478 | date filter3Min; 479 | date filter3Max; 480 | ... 481 | } 482 | 483 | 484 | class BiometricData { 485 | byte[] image; 486 | URL imageRef; 487 | } 488 | 489 | Encounter o-- "*" BiometricData 490 | 491 | class Template { 492 | byte[] buffer; 493 | string format; 494 | } 495 | BiometricData -- Template 496 | 497 | class Candidate { 498 | int rank; 499 | int score; 500 | } 501 | Candidate . Person 502 | 503 | class CandidateScore { 504 | float score; 505 | string encounterID; 506 | enum biometricType; 507 | enum biometricSubType; 508 | ... 509 | } 510 | Candidate -- "*" CandidateScore 511 | --------------------------------------------------------------------------------