PHP2Shell alert: critical PHP flaws CVE-2026-109618 / 109619 — check your servers and get patched fast
HashTech Systems
EV Charging
Part 4 of 12

OCPP 1.6 Authorize, Local Auth List and Authorization Cache

How OCPP 1.6 authorizes drivers: Authorize and IdTagInfo, the local authorization list, the authorization cache, and how chargers behave offline.

HashTech Engineering · October 26, 2026 · 6 min read

Before a charger delivers energy it needs to know whether the driver is allowed to charge. In OCPP 1.6 that decision revolves around the idTag: an identifier, usually an RFID card UID, that the CSMS validates. This part covers the Authorize message, the IdTagInfo structure that appears in several responses, and the two local mechanisms (the local authorization list and the authorization cache) that let a charger decide without asking. It is part 4 of the series; for the wider payment picture see EV charging payment options.

Authorize

json
[2, "au-2201", "Authorize", {"idTag": "04A2B3C4D5E680"}]
json
[
  3,
  "au-2201",
  {
    "idTagInfo": {
      "status": "Accepted",
      "expiryDate": "2026-10-27T09:00:00Z",
      "parentIdTag": "FLEET-ACME-01"
    }
  }
]

idTag is an IdToken, a CiString20. That means a maximum of 20 characters and case-insensitive comparison. RFID UIDs are usually sent as uppercase hex, but chargers differ on byte order and on whether they include separators, so the same physical card can arrive as 04A2B3C4D5E680 from one model and 80E6D5C4B3A204 from another. Normalise per hardware model at the edge of your system rather than registering every variant.

IdTagInfo

IdTagInfo appears in the responses to Authorize, StartTransaction and StopTransaction, and in local authorization list entries.

FieldRequiredMeaning
statusYesAuthorizationStatus, see below
expiryDateNoWhen the charger should stop treating this cached result as valid
parentIdTagNoGroup identifier; tags with the same parent are treated as the same user
AuthorizationStatusMeaning
AcceptedAllowed to charge
BlockedIdentifier blocked
ExpiredIdentifier expired
InvalidIdentifier unknown or not valid
ConcurrentTxIdentifier already in an ongoing transaction and concurrent transactions are not allowed

parentIdTag has a practical use: it lets a charger stop a transaction when a different card of the same group is presented. A fleet operator with many cards under one account can stop a session started by one driver with another driver's card, because both share the parent. Without it, only the exact idTag that started the transaction (or the CSMS) can stop it.

When the charger calls Authorize

A charger calls Authorize when a driver presents an identifier locally, before it starts a transaction. For remote starts the behaviour depends on the AuthorizeRemoteTxRequests configuration key: if true, the charger authorizes the idTag from RemoteStartTransaction before starting; if false, it trusts the CSMS. Since the CSMS sent the remote start, setting it to false avoids a pointless round trip. To stop a transaction, the charger may skip Authorize when the presented idTag is the same one that started it.

There are also two related keys. LocalPreAuthorize lets the charger start immediately when the tag is found as valid locally (cache or list), without waiting for the CSMS. LocalAuthorizeOffline lets the charger use local data when it is offline. With both enabled, a returning driver with a cached card starts charging instantly whether or not the backend is reachable.

The authorization cache

The cache is automatic. Whenever the charger receives an IdTagInfo from the CSMS, in an Authorize, StartTransaction or StopTransaction response, it can store the result. It is enabled through the AuthorizationCacheEnabled key, and the CSMS can clear it with ClearCache:

json
[2, "csms-cc-1", "ClearCache", {}]
[3, "csms-cc-1", {"status": "Accepted"}]

The cache is only as good as the expiryDate you set. If you return Accepted with no expiry, a card you later block can keep working offline on any charger that cached it. Set a sensible expiry, and use ClearCache when you need a block to take effect immediately. Even so, a charger that is offline when you send ClearCache cannot receive it.

The local authorization list

The local authorization list (Local Auth List Management profile) is managed explicitly by the CSMS. It takes precedence over the cache, it has a version number, and it is the right tool for fleets, depots and private sites where a known set of cards must work even if connectivity is poor. It is enabled through LocalAuthListEnabled, and the charger advertises its capacity in LocalAuthListMaxLength and the maximum number of entries per message in SendLocalListMaxLength.

SendLocalList

json
[
  2,
  "csms-ll-7",
  "SendLocalList",
  {
    "listVersion": 42,
    "updateType": "Differential",
    "localAuthorizationList": [
      {
        "idTag": "04A2B3C4D5E680",
        "idTagInfo": { "status": "Accepted", "parentIdTag": "FLEET-ACME-01" }
      },
      {
        "idTag": "04FF0011223344",
        "idTagInfo": { "status": "Blocked" }
      },
      {
        "idTag": "0499AA88BB7766"
      }
    ]
  }
]

updateType is Full or Differential. A Full update replaces the entire list. A Differential update adds or updates entries that include idTagInfo and removes entries that omit it; in the example, the third tag is deleted. The response status is one of Accepted, Failed, NotSupported or VersionMismatch.

GetLocalListVersion

json
[2, "csms-ll-8", "GetLocalListVersion", {}]
[3, "csms-ll-8", {"listVersion": 42}]

A listVersion of 0 means the list is empty and -1 means the charger does not support a local list. Use the version to detect drift: if the charger reports a version other than what you last sent, send a Full update. That includes after a factory reset or board replacement, which wipes the list without telling you.

Offline behaviour

When the charger cannot reach the CSMS and a driver presents a tag, the decision is:

  1. If LocalAuthorizeOffline is true and the tag is in the local list or cache with a valid status, accept it.
  2. If the tag is unknown and AllowOfflineTxForUnknownId is true, accept it anyway. This is a convenience setting: anyone with any RFID card can charge while the charger is offline.
  3. Otherwise refuse.

When connectivity returns, the charger sends the queued StartTransaction. The CSMS answers with the real IdTagInfo. If the tag turns out to be invalid and StopTransactionOnInvalidId is true, the charger stops the transaction (with reason DeAuthorized); if false, the transaction stays open but the charger stops energy delivery, or limits it where MaxEnergyOnInvalidId is configured. This is covered with message examples in part 5.

Field gotchas

  • Leading zeros and byte order in RFID UIDs. Compare normalised values, and keep a raw copy for support.
  • Some chargers send a placeholder idTag for free-vend or plug-and-charge-like modes. Know which models do this before you treat it as a real user.
  • Returning Invalid for a tag that is merely out of credit stops the driver without a useful message on screen. If the charger has a display, consider Blocked vs Invalid carefully, and use the status your support team can explain.
  • Contactless payment terminals and apps often use the idTag field to carry a session or payment reference. Keep that within 20 characters and make it unique per session.

Key takeaways

  • IdTagInfo (status, expiryDate, parentIdTag) drives authorization everywhere in 1.6.
  • The local list is CSMS-managed and versioned; the cache is automatic and controlled by expiry and ClearCache.
  • Offline behaviour is configured, not fixed: review LocalAuthorizeOffline, AllowOfflineTxForUnknownId and StopTransactionOnInvalidId for each site.

Previous: Part 3, StatusNotification. Next: Part 5, StartTransaction and StopTransaction. For the OCPP 2.0.1 equivalent, see OCPP 2.0.1 authorization.

Let's Talk

Ready to build something that lasts?

Whether it's a charging network, an AI rollout, or a core enterprise system — let's talk about what you're building.