Skip to main content

Aliro API

Scope note: this page covers external Org API methods for Aliro operations from proto/org.proto.

Methods​

  • SetAliroConfig(SetAliroConfigRequest)
  • SetAliroAccessElementIdentifiers(SetAliroAccessElementIdentifiersRequest)

Supported fields only​

This public API currently supports only the fields documented on this page.

  • For SetAliroConfig, only:
    • device_id
    • reader_group_id
    • reader_certificate
    • issuer_public_keys (single key)
    • credential_issuer_ca
    • access_document_element_ids
    • reader_system_issuer_ca_pub_key
  • For SetAliroAccessElementIdentifiers, only:
    • data_element_identifiers[]

No additional Aliro request structures are supported through these methods at this time.

SetAliroConfig​

Configures Aliro reader provisioning inputs per device.

Request shape:

  • configs[].device_id: target device
  • configs[].reader_group_id: exactly 16 bytes
  • configs[].reader_certificate: optional DER X.509 reader certificate (when provided, Link compresses this to Profile0000 before sending to device)
  • configs[].issuer_public_keys: optional, limit is 1, each key is a 65-byte uncompressed P-256 public key (0x04 || X || Y)
  • configs[].credential_issuer_ca: optional DER X.509 Credential Issuer CA certificates trusted for Access Document x5chain verification
  • configs[].access_document_element_ids: optional Access Document element IDs
  • configs[].reader_system_issuer_ca_pub_key: optional 65-byte uncompressed P-256 Reader System Issuer CA public key (0x04 || X || Y)

Behavior:

  • Request fails with InvalidArgument if any config entry is invalid.
  • Request fails with NotFound if any device_id does not exist.
  • On success, Link enqueues Aliro provisioning operations for each listed device.

Public / Private Key Flow Playbook​

1. Get the reader public key from the Org API​

Fetch the target device via Org.ListDeviceSummaries and read summary.aliro_reader_public_key from DeviceSummary.aliro_reader_public_key in proto/org.proto.

This field is the raw reader public key, not a CSR. The expected format is the 65-byte uncompressed P-256 point: 0x04 || X || Y.

If aliro_reader_public_key is unset, the device has not yet reported or completed the Aliro provisioning step that captures it.

Example Python check:

assert len(reader_pubkey_65) == 65
assert reader_pubkey_65[0] == 0x04

Treat DeviceSummary.aliro_reader_public_key as the source of truth for integrations. Link may also return an AliroReaderPublicKeyCaptured audit through Org.ListAudits and Org.StreamAudits when the reader key is captured. Consumers can use that audit as a notification to re-read the device summary.

Link also emits a general device writable/readiness audit when the device becomes ready for normal writes; that audit has audit.writable = true and an audit.audit_type of DeviceLifecycle.

2. Generate an Aliro pass​

Using the reader public key, generate an Aliro pass in your system.

3. Call SetAliroConfig​

Using the reader group id from your newly issued Aliro pass, call SetAliroConfig to configure the device.

DO NOT provide reader_certificate and issuer_public_keys in this step otherwise the public key flow will not work.


org.SetAliroConfig(org_pb2.SetAliroConfigRequest(
configs=[
org_pb2.AliroConfigForDevice(
device_id=600000,
reader_group_id=reader_group_id,
)
]
))

Notes:

  • reader_group_id must be exactly 16 bytes.
  • reader_certificate and issuer_public_keys are optional for this step; provide them only if you are also sending reader certificate material.
  • credential_issuer_ca, access_document_element_ids, and reader_system_issuer_ca_pub_key are optional provisioning inputs for Access Document validation.

4. Call the Assign RPC to provision the pass onto the device​

After you generate the Aliro pass, assign its user device long-term public key to the device with Org.Assign.

For Aliro passes, the credential payload is:

  • credential_type = ALIRO_UD_PUBLIC_KEY
  • data = the Aliro user device public key as a 65-byte uncompressed P-256 point (0x04 || X || Y)

Example:

from credential_pb2 import Credential, ALIRO_UD_PUBLIC_KEY
import org_pb2

req = org_pb2.AssignmentsRequest()
req.assignments[600000].credentials.append(
Credential(
credential_type=ALIRO_UD_PUBLIC_KEY,
data=aliro_ud_public_key,
)
)

org.Assign(req)

Notes:

  • The assignments map is keyed by device_id.
  • data must be unique for the credential and should contain the pass's Aliro user device public key.

Reader Certificate Playbook​

This section is the practical setup flow for SetAliroConfig.

Terminology used below:

  • Reader public key: raw reader public key bytes (P-256), not a full CSR document.
  • Reader certificate: the signed cert produced for that reader public key (reader.crt / reader.der) and sent as reader_certificate.
  • Issuer CA: the CA that signs the reader certificate.
  • issuer_public_keys: the Reader System Issuer CA public key bytes, not the reader leaf public key.

1. Get the reader public key from the Org API​

Fetch the target device via Org.ListDeviceSummaries (or consume Org.StreamDeviceSummaries / Org.StreamDeviceUpdates) and read summary.aliro_reader_public_key from DeviceSummary.aliro_reader_public_key in proto/org.proto.

This field is the raw reader public key, not a CSR. The expected format is the 65-byte uncompressed P-256 point: 0x04 || X || Y.

If aliro_reader_public_key is unset, the device has not yet reported or completed the Aliro provisioning step that captures it.

Example Python check:

assert len(reader_pubkey_65) == 65
assert reader_pubkey_65[0] == 0x04

2. Build a reader certificate from the raw reader public key and sign with the issuer CA​

Convert the raw reader public key to PEM SubjectPublicKeyInfo (example helper):

from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.asymmetric import ec

pub = ec.EllipticCurvePublicKey.from_encoded_point(ec.SECP256R1(), reader_pubkey_65)
with open("reader_pub.pem", "wb") as f:
f.write(pub.public_bytes(
encoding=serialization.Encoding.PEM,
format=serialization.PublicFormat.SubjectPublicKeyInfo,
))

Create a cert request config using that public key (reader_cert.cnf):

[ req ]
distinguished_name = dn
x509_extensions = v3_req
prompt = no

[ dn ]
CN = subject

[ v3_req ]
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
authorityKeyIdentifier=keyid

Issue/sign certificate from the public key:

openssl x509 -new \
-key reader_ca.key \
-CA reader_ca.crt \
-CAkey reader_ca.key \
-CAcreateserial \
-days 825 \
-sha256 \
-subj "/CN=subject" \
-force_pubkey reader_pub.pem \
-extfile reader_cert.cnf \
-out reader.crt

Link validates the resulting X.509 cert for Aliro compatibility. Ensure:

  • ECDSA P-256 key
  • Signature algorithm: ECDSA with SHA-256
  • v3 certificate
  • Extensions include:
    • authorityKeyIdentifier (non-critical, keyid length 20 bytes)
    • basicConstraints (critical, CA:FALSE)
    • keyUsage (critical, digitalSignature)

Example ext file (reader_ext.cnf):

basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature
authorityKeyIdentifier=keyid

Convert to DER for API request:

openssl x509 -in reader.crt -outform DER -out reader.der

3. Build issuer_public_keys entry from the issuer CA public key (65-byte uncompressed key)​

issuer_public_keys accepts exactly one key, encoded as:

  • 0x04 || X || Y (65 bytes total, P-256 uncompressed SEC1 format)

If you have the reader CA public key PEM, extract bytes with Python:

from cryptography.hazmat.primitives import serialization

with open("reader_ca_pub.pem", "rb") as f:
pub = serialization.load_pem_public_key(f.read())

reader_ca_pubkey_65 = pub.public_bytes(
encoding=serialization.Encoding.X962,
format=serialization.PublicFormat.UncompressedPoint,
)
assert len(reader_ca_pubkey_65) == 65 and reader_ca_pubkey_65[0] == 0x04

4. Call SetAliroConfig​

with open("reader.der", "rb") as f:
reader_cert_der_bytes = f.read()

org.SetAliroConfig(org_pb2.SetAliroConfigRequest(
configs=[
org_pb2.AliroConfigForDevice(
device_id=600000,
reader_group_id=b"\x01" * 16,
reader_certificate=reader_cert_der_bytes,
issuer_public_keys=[reader_ca_pubkey_65], # exactly 1 key
)
]
))

Notes:

  • reader_group_id must be exactly 16 bytes.
  • reader_certificate must be DER X.509; Link compresses to Aliro Profile0000 before device delivery.
  • issuer_public_keys hard limit is 1 entry.
  • reader_system_issuer_ca_pub_key, when supplied, is a 65-byte uncompressed P-256 public key used by the device to validate the reader certificate.
  • credential_issuer_ca entries are DER X.509 CA certificates used for Access Document x5chain verification.

5. Send requested Access Data Element identifiers​

Temporary behavior: requests with any non-empty data_element_identifiers are currently rejected with InvalidArgument.

Once config is set, request the Access Data Element identifiers needed by your reader policy:

org.SetAliroAccessElementIdentifiers(org_pb2.SetAliroAccessElementIdentifiersRequest(
requests={
600000: org_pb2.AliroAccessElementIdentifiers(
data_element_identifiers=["administrator", "floor1"]
)
}
))

SetAliroAccessElementIdentifiers​

Sends Aliro Access Data Element identifier requests to one or more devices.

Request shape:

  • requests: map of device_id -> { data_element_identifiers[] }

Only data_element_identifiers[] is consumed by this method.

Validation:

  • Maximum identifiers per device: 16
  • Maximum identifier length: 128 characters
  • Empty list is allowed
  • Empty identifier strings are rejected

Behavior:

  • Request fails with InvalidArgument if validation fails.
  • Request fails with InvalidArgument if any data_element_identifiers are provided (temporary behavior).
  • Request fails with NotFound if any device_id does not exist.
  • On success (empty identifiers only), no access element identifier operation is queued.

Python example​

import org_pb2

# 1) Set Aliro provisioning config
org.SetAliroConfig(org_pb2.SetAliroConfigRequest(
configs=[
org_pb2.AliroConfigForDevice(
device_id=600000,
reader_group_id=b"\x01" * 16,
reader_certificate=reader_cert_der_bytes,
issuer_public_keys=[issuer_pubkey_65_bytes], # exactly 1 key
)
]
))

# 2) Request Access Data Element identifiers
org.SetAliroAccessElementIdentifiers(org_pb2.SetAliroAccessElementIdentifiersRequest(
requests={
600000: org_pb2.AliroAccessElementIdentifiers(
data_element_identifiers=["administrator", "floor1"]
)
}
))