Altinn/app-template-dotnet

Analysis and design: Signing

RonnyB71 opened this issue · 3 comments

Background and scope

Description

We have previously analyzed requirements for signing functionality in Altinn 3 described in:

While these are still relevant, they cover a broader scope than than necessary for a first implementation and are in some parts outdated as new requirements and thoughts have been discussed. They are however still an important reference for the areas still relevant.

What type of electronic signature will we support?

EU through the eIDAS Regulation have defined 3 levels for electronic signatures. The intention in this epic is to support the Simple level as the two higher levels are covered by eSignering - a separate product from Digdir.

This level does not rely on the use of a public-key infrastructure (PKI), but rather the strength of the signature is accomplished through strong login methods and traceability in data and logs stored. Read the following guide
for best practices on traceability.

In scope

The current analysis, requirements and design seeks to cover what in Altinn 2 is known as process templates related to signing:

  1. Form filling and signing (Utfylling og signering)
  2. Form filling and conditional signing (Utfylling og betinget signering)
  3. Form filling and double signing (Utfylling og dobbel signering)
  4. Form filling and conditional double signing (Utfylling og betinget dobbel signering)

While the signing feature in Altinn 2 is bound to fixed process templates, we seek to create process support in such a way that you have flexibility in the way you design your signing (or other) process.

The analysis and design part of this document will cover the above mentioned processes, but the implementation tasks will potentially be split into multiple epics seeking to deliver value as soon as possible. The priorities for the initial version will be targeting bullet point 3 (Form filling and double signing) as we already have to service owners with applications targeting this feature. However, done right, we most likely will have implemented bullet point 1 as well as that should be a matter on how you design your process.

Out of scope

  • Parallel signing (Parallell signering) - no application deliveries requiring this feature is identified for 2023. This feature is likely to be delivered in 2024.
  • Advanced Electronic Signatures (AdES) or Qualified Electronic Signatures according to the eIDAS Regulation. These types of signatures are a feature in Digdir's eSignering product and will not be delivered as a feature in Altinn 3.
  • Integrating with eSignering or other commercial signing providers, this is an possibility for future releases.

The process

The foundation for the requirements is to be able to support the following processes illustrating bullet point 3 above Form filling and double signing.

signering drawio

Note that 1 or 2 signing steps, or 3 for that matter, should not affect the implementation but rather be a consequence of how the process is designed and described in the BPMN file in the app. Ie. doing this right should also cover bullet point 1.

The diagram above is a visual representation of a BPMN process. The BPMN process is defined in XML within each Altinn 3 app. While the process can vary from app to app, most apps until now have very simple processes implemented, and most without any gateways. An Altinn 3 app doesn't support any BPMN process, but rather a small subset of the symbols defined. We will however extend the support by gradually by adding the necessary symbols for the most basic processes. When support for new symbols is added it should follow the current BPMN Specification. Good and correct BPMN support is essential to be able to support the various signing processes.

While the process above shows the process steps within the application, the process below shows the various user interactions. A process step might have multiple user dialogs and these aren't represented within the application's BPMN process but are rather built into the frontend application as a consequence of actions taken.

signering-brukerflyt

NOTE! After a few discussions we have decided to focus on the simple workflow illustrated in the first process diagram. This means that confirmation dialogs are out and replaced with a generic no-access layout in the first delivery.

Design

Utfylling men ikke rett til bekreftelse, Utfylling og bekreftelse, og Dobbelt signering
Bekreftelse flyter

  1. When you only have rights to fill out the form and no rights to confirm on the behalf of the organization. You get to a general "you have no rights" page, and the form is sent to someone who has.

  2. When you have rights to fill out the form and the rights to confirm on the behalf of the organization.

  3. When the form requires a confirmation/signature from both the organization and an accountant (revisors bekreftelse)

Figma file: https://www.figma.com/file/wnBveAG2ikUspFsQwM3GNE/Altinn-Studio-Apps?node-id=23849%3A56389&t=WEXbgDprboerYOlG-1

Functional requirements

  1. It should be possible to sign the instance on one or many different process tasks.
  2. Given that the user have access to sign, it should be possible to fill out the form and sign it within the same process step.
  3. It should be possible to define the role requirement for the process task controlling who's allowed to sign.
  4. For applications with multiple signing tasks it should be possible to configure that the signature is unique across signature steps ie. the same user cannot sign off on multiple steps even if he/she has the roles to do so.
  5. The signee should be informed about the data he/she is about to sign off on
  6. The signature should be captured and logged explicitly in the system allowing for Digdir to prove that the action was done.
  7. The signature should captured in it's own data object.
  8. It should be possible to design the signature view/layout
  9. The signature and logs should be kept for 10 years
  10. The signature object should be deleted as part of instance deletion as it's just data connected to the instance
  11. Log entries should not be deleted as part of instance deletion

Functional requirements identified but pushed to later delivery

  • It should be possible to add comments about the signature
  • A signer should be given access to a PDF presentation of the forms he/she is signing
  • It should be possible to configure an external signature view for binary attachments and select attachments to sign
  • It should be possible to download attachments to be signed from the signature view
  • The signer should get a separate receipt for the signing step. How?

Technical solution

As a general guideline we should be true to the BPMN standard and not have our own customized implementation.

Frontend

  • No-access layout
    The frontend application today supports one layout for a given step. This supports read/edit mode ie. the user has at least read access to the step itself. We need a layout representing the UI to be displayed if the user don't have access to the step. A first step could be to limit this to texts and information, but the we should be able to add components to this layout as well. For example to send a reminder to someone responsible for moving the process forward.
  • Dialog consept (not part of the first delivery)
    Today a layout defines the UI to be rendered, but sometimes you need a dialog as a response to an action triggered by a component. Ie. you click a button to sign/confirm and send the process to the next step. A dialog in this case could be confirming to the user that the process is sent to the next step. A complicating factor in this case is that if the user has access to the next step, we would like to skip the dialog and just present the next step.
  • No-process knowledge in frontend
    Frontend should not know about the BPMN process. It should get information from backend regarding what step the user is on and the layout to use. This does not include dialogs mentioned above. Dialogs are a frontend there-and-then thing bound to the components triggering them.
  • Signature/confirm button
    Frontend needs to provide either a new type of sign/confirm button in addition to the two types we have today - submit and navigation. This is basically a submit button with a sign parameter set to trigger det correct backend actions. A special signature component has been discussed, but for now we think a button will do. This also means we are not looking to create a special signature step, but rather have a signature button that can be added on any kind of process step. The simplest form of process could then be one data step with a sign button instead of a submit button. Next would be a to step process with data and confirm step with a sign button.

Backend

  • Recognizing a signature step
    Backend cannot trust frontend to either send the sign parameter or not, but needs a way of recognizing a step that requires a submit with a sign attribute set in order to move on to the next step in the process.

  • Signature data element
    Each signature action should result in a separate signature document stored as a signature datatype/document along side the other datatypes in the application. The signature document needs to contain the following information:

    • Which user or organization signed document (userId/partyId, ssn,orgno)
    • The instance the signature is related to
    • The task for the signing step that performed the signing
    • A list of all data elements that are included in the signature and not. With room for comments
    • A hash of all documents

    Example json structure:

      {
          "id" : "b80f910a-bde0-49e5-8ccf-7c9ba851eb28",
          "time" : "2018-04-05T17:31:00Z"
          "instanceguid" : "74df5b79-74cc-4731-930a-d2accde7084b",
          "signaturecomment" : "Dokumentasjonen på fradraget viser at dette er I henhold til skattelovgigning av 17. mai 1982",
      
          "signer" : {
            "userid" : 5,
            "partyid" : 5,
             "secondarysignerid" : "person/01038712345"
             },
          "data" : 
          [{
            "dataid":"533e302b-d5f7-44a7-a2b4-bd5fbb1ddea2",
             "md5hash": "23423424",
              "signed": true,
              "comment" : "Her er beviset"
            },
            {
            "dataid":"be7b5a28-579e-4f55-a005-55f78c9c2b99",
             "md5hash": "23423424",
              "signed" : false,
              "comment": "Her har eier gått langt for streken. Kan ikke signere på disse dokumentene"
            },
            {
            "dataid":"ba94413d-c31a-452b-9466-438cd5ed7fd2"
             "md5hash": "23423424"
            }
          ]
          "signedtask" : "sign1",
      }
  • Explicit logging of signature action
    Once a signture action is completed and the signature document is created an explicit log entry should be created. This can be achieved in multiple ways:

    1. Regular application logging
    2. Triggering a signing event including logging when the signing process is completed
    3. Logging to an Audit log
    4. Logging to a TTP log

    While all types provides a log entry they range from standardized log formats where the entry can be hard to find to specialized formats where the entry is easy to find and provides a higher level of trust.

  • Expression on gateways
    A gateway can have two or more outcomes. These should be possible to describe using the newly implemented expression language as well has

Questions to be discussed

Questions related to the format of the signature document to be discussed

  • userid and partyid are internal id's in Altinn and should probably not be leaked out. Instead we should standardize on person number and organization number
  • md5hash is a fixed algorithm, this should be replaced with an "hashAlgorithm": "md5", "hashValue":"234534345"
  • should comments be included in this format or stored as a separate datatype?
  • are there any standard formats that we could rely on for this?
  • do we need to support file signing in the first version?

Questions related to logging

  • what log level should we aim for?

Questions related to access

  • The process currently don't support a user not having at least read access. Having no access at all to one step, but access to others have been raised as a complicating issue. While this isn't critical for the first version it should be discussed.

Tasks

  1. area/signing feature-complete kind/user-story
    bjosttveit
  2. area/signing feature-complete kind/user-story
    RonnyB71 tjololo
  3. feature-complete kind/user-story
    tba76
  4. feature-complete kind/user-story
    tjololo
  5. feature-complete kind/user-story
    tjololo
  6. area/summary feature-complete kind/user-story
    framitdavid
  7. kind/other

Related tasks not included in first delivery

Test app for signing

Set up so that one role can fill out the data step, but another role is required for confirmation. The first role has read access to the confirmation step, but will throw an error when clicking on the confirm button.

Front-end requirements

Currently, app-frontend needs to get information about which actions are available in the current step, and whether or not the current user has permission to perform those actions. This could be included in the process response:

image

The process state is currently included in several requests, GET /.../process, GET /.../instances/{instance-id} and PUT /.../process/next. The first two requests are fetched on reload, and the last two when going to a new process step. Maybe including this data in so many places is unnecessary?

I don't know how the policy is represented in the backend/authorization, but I would expect to get a response similar to:

{
  ...
  "currentTask": {
    "read": true,
    "write": false,
    "actions": {
      "confirm": false,
      "instantiate": false,
      "sign": true,
      "reject": true
    },
    ...
  },
  ...
}

To give instance the correct status in Altinns Meldingsboks we need to add the correct return value for the tasktype signing (or what we decide to call it) here: https://github.com/Altinn/altinn-storage/blob/main/src/Storage/Helpers/InstanceHelper.cs#L97