Skip to main content

One post tagged with "security"

View All Tags

· 3 min read

When you need more than “a signature,” identity enforcement links a Swedish personal identity number (personnummer) to a signer and forces strong authentication (Mobile BankID/ZealID) before the signature can complete. If the authenticated identity doesn’t match, the signing is blocked.

What is the benefit of identity enforcement?

Sometimes it is critical that a specific person is the one signing an agreement. For example, only a certain individual may be authorized to sign a purchase order. In the past, some providers such as BankID allowed you to initiate authentication for a specific personal number. However, this approach is becoming increasingly rare, since it creates security and impersonation risks. If a signing session can be triggered remotely for a given identity, there is no guarantee that the actual signer is the one present in the signing room. By requiring the scanning of a QR code or starting the authentication session directly from the signing room, these risks are significantly reduced.

The drawback is that anyone with access to the signing room link could still complete the signing. Because recipients sometimes share links carelessly, this can be a serious problem in compliance-heavy environments.

Our solution combines the best of both worlds. Instead of starting a signing session for a fixed personal number, identity enforcement cross-checks the signer’s identity after authentication. This ensures that impersonation and remote signing risks are mitigated while also discarding any invalid signatures.

How it works

Identity enforcement must be configured while the agreement is still in draft. You attach the participant’s personal number under the identity_enforcement object. At signing time, the participant is required to authenticate using Swedish Mobile BankID. Zigned automatically cross-checks the authenticated identity against the stored personal number, and the participant’s status moves from pending to either passed or failed.

You can combine identity enforcement with a lower trust level to enforce stricter signing methods for a specific participant. For example, if you set trust_level: SES along with identity enforcement, the participant is only allowed to sign using advanced methods. Identity enforcement also works with qualified signatures (QES), ensuring the strongest level of eIDAS-compliant signing.

Privacy and compliance

Personal numbers are handled with the same care as sensitive credentials. They are normalized and stored using hash-based encryption, meaning the original value is never persisted in plain form. All verification is done against these hashes, ensuring that identity enforcement is fully GDPR compliant while maintaining strong privacy guarantees.


Example: Creating a signer with identity enforcement

// POST /agreements/:agreement_id/participants
import fetch from 'node-fetch'

async function addSignerWithIdentity(agreement_id: string, token: string) {
const body = {
role: 'signer',
email: 'anna@example.com',
name: 'Anna Andersson',
personal_number: '198512149999',
}

const res = await fetch(`https://api.zigned.se/agreements/${agreement_id}/participants`, {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify(body),
})

if (!res.ok) throw new Error(`Create participant failed: ${res.status}`)
return res.json()
}

Tracking outcomes

When retrieving a participant, you’ll see an identity_enforcement object describing the state:

{
...participant,
"identity_enforcement": {
"enabled": true,
"status": "passed",
"enforcement_method": "swe_pno_crosscheck"
},
}

A status of "passed" confirms that the participant authenticated correctly with the provided personal number. "failed" indicates that the identity check did not match, and the signing attempt is blocked.

In conclusion

Identity enforcement is a powerful tool for ensuring that only the intended signer completes a signing process. Our approach not only enhances security but also ensures compliance with privacy regulations. To get started, you only need to pass in a personal_number when creating a participant. Easy-peasy!