24 August, 2026

Authorization across half a continent

Inside the engineering of remote tachograph communication

Let me tell you a telematics story spanning 14 years – 12 of them spent working with tachographs. A story about how it really works: where the hardware lies, why the specification is never the ultimate source of truth, what users keep running into, and why this kind of knowledge can't be bought or generated by AI. Just the truth that nobody else is going to tell you.

A quick primer

In a nutshell, a tachograph is an onboard recorder used in commercial vehicles. Under EU legislation, it is mandatory in all commercial goods vehicles with a maximum permissible mass (including trailers) exceeding 3.5 tonnes. From July 1, 2026, the requirement also applies to vehicles over 2.5 tonnes engaged in international transport. For passenger transport, tachographs are required in vehicles with more than 9 seats, including the driver's seat. A tachograph records everything about the vehicle's operation – how, where, how far, and for how long it was driven – along with detailed driver activity, including driving time, rest periods, breaks, and more.

Transport authorities check everything: from whether a tachograph is installed to compliance with drivers' hours regulations. Violations can result in fines reaching tens of thousands of euros, loss of operating licences, and serious reputational damage. In some countries, tampering with a tachograph is even a criminal offence. The regulations also require that tachograph data be downloaded at least every 90 days and driver card data every 28 days, and that both be stored for at least 12 months. They must also be provided to transport inspectors on demand. Otherwise, as we've already established – penalties follow.

Since vehicles are often thousands of kilometres apart, manually downloading data by physically connecting to each tachograph is hardly something anyone in their right mind would do today. That's exactly why flespi lets you do it remotely, making the process as simple and painless as possible: insert the company card into a card reader, launch the authorization application, send the command to download the tachograph file, and about 7-10 minutes later the file will appear in the device's storage.

With the boring part out of the way, let's move on to what actually happens under the hood while all of this is going on.

Authorization

The company card is sitting in a card reader at the office. The tachograph is installed in a truck somewhere halfway across the continent (although that's really just a detail). You could mount the tachograph on a spacecraft if you wanted – as long as it has an internet connection. The card has no idea where it actually is: from its perspective, the conversation is the same as if it were plugged directly into the tachograph.

An authorization session with the tachograph takes about 15 seconds on average and starts immediately after you send the command. A few minutes later, the file download begins, and a few more minutes after that, the completed file is stored and ready to use.

The communication itself consists of APDU commands – atomic requests exchanged with the smart card according to the ISO 7816 standard, typically just a few dozen bytes each. 

A curious detail: the EU tachograph regulation is free and open. The ISO 7816 standard it relies on is not — ISO is a non-governmental organization that sells its standards. To implement an open regulation, you need a closed paid standard.

A command originates in the tachograph, travels through the truck's CAN bus, the tracker's firmware, the cellular network, the flespi server, the internet, the application running on the office computer, and finally the card reader before it reaches the card's chip. The response takes the same route back. Eleven hops there, eleven hops back – every single command.

The conversation itself has four phases: introduction, tachograph verification, card verification, and the establishment of a secure channel.

The four phases under the microscope

The regulation refers to this entire process as mutual authentication. And yes, every single phase can fail.

Phase 1 – Introduction. The tachograph reads the card's identifiers and the list of applications stored on the chip. Yes, a single card can contain multiple applications, and the tachograph must select the correct one. Things can already go wrong here – for example, if the card in the reader isn't a tachograph card at all.

Phase 2 – Tachograph verification. The tachograph presents the card with a certificate chain rooted in the European Certificate Authority and signs a challenge generated by the card. The card verifies everything: the certificates are valid, and the signature matches, so the device on the other end really is a genuine tachograph, not something pretending to be one.

Phase 3 – Card verification. Now the roles are reversed. The card proves to the tachograph that it is genuine. During the same exchange, both sides independently derive identical session keys – identical, yet never transmitted across the communication path in plain form.

Phase 4 – Secure channel. From this point on, every message is encrypted and authenticated using those session keys. Every command and every response is assigned a sequence number. This is where the 11-hop chain must work flawlessly, because what comes next is the most fragile part of the entire process.

Both sides maintain their own sequence counters independently, and those counters must stay perfectly synchronized throughout the session. If they get out of sync by even a single number, the signatures no longer match, the secure channel is considered compromised, and the authorization has to start from scratch. Cryptography doesn't care that "the network hiccupped." Either you begin again, or a recovery mechanism steps in, identifies the point of failure, and resumes the session – seamlessly from the user's perspective. Cryptographically, it's still a brand-new authorization; the user just never notices.

Throughout all of this, the client sees a loading spinner. And that's the successful case.

If we oversimplify it, the whole purpose of the authorization process is to deliver a command from the tachograph to the company card and return the card's response. Sounds straightforward enough. In reality, though, it's slightly more complicated.

Let's start with the abstractions. We'll break each one down and then put them back together in chronological order. There are four of them:

  • Authorization application

  • Server

  • Tracker

  • Tachograph

Authorization application

Let's use the flespi implementation as an example – the Tacho Bridge App. The application acts as the bridge between the server and the company card. All communication is wrapped in a custom protocol running on top of MQTT. In practice, it's simply JSON data flowing in both directions. Its primary responsibility is to act as a proxy between the company card and the server. Under the hood, however, there are many other complex mechanisms that you need to both understand thoroughly and keep firmly under control.

Application logic

  • MQTT client – maintains a persistent connection to the flespi server: subscribes to commands, publishes responses, and reports card status. Office networks are just as prone to hiccups as cellular ones, so the application has to handle reconnects, restore subscriptions, and keep track of messages that still need to be delivered.

  • Card and reader registry – the application must always know what it's working with: detect when card readers are connected or disconnected, notice when a card is inserted or removed, read its identifiers, and report back to the server: "the card is present and ready."

  • Session orchestration – a company card can handle only one session at a time, while the company may have hundreds of tachographs. That means command queues for each card, mapping every command to the correct card, tracking timeouts for every step, and cleaning up sessions that get stuck.

The smart card stack

  • PC/SC – the universal standard that defines how a computer communicates with smart cards: one API for any reader on any operating system. At least, that's the theory. In practice, it's only universal on paper. Reader manufacturers add their own proprietary features; some hardware – such as racks holding hundreds of cards – doesn't fit the standard at all, and every operating system implements it differently.

    • WinSCard on Windows is the historical reference implementation. The standard was developed with Microsoft's involvement, and other implementations largely followed its lead.

    • pcsc-lite with the pcscd daemon on Linux. Here's a fun fact: the whole thing is effectively maintained by one person. For more than twenty years, both pcsc-lite and the universal CCID driver used by nearly every USB smart card reader on Linux have been maintained by Ludovic Rousseau. The infrastructure that banks, government agencies, and the entire European tachograph ecosystem rely on under Linux is, essentially, one French developer's long-running hobby project. A pretty good horror story about how fragile the foundations of modern software can be :)

    • Apple, being Apple. For many years, macOS shipped with a fork of that same pcsc-lite. Then Apple rewrote everything and closed it off. The familiar PC/SC interface is still there, but now it's a thin compatibility layer on top of a completely different architecture – compatible in spirit rather than a native implementation.

  • So in the end, we have one standard and three different implementations, each with its own timeouts, bugs, undocumented quirks, error codes, and different behavior in identical situations.

  • Language wrapper. The application doesn't communicate directly with the operating system's smart card subsystem. Instead, it goes through a language-specific wrapper that exposes a more developer-friendly API. Every language has its own: the pcsc crate in Rust (used by Tacho Bridge App), pyscard in Python, and the built-in smartcardio package in Java. Convenient? Absolutely. But there's a catch: every wrapper is yet another independent implementation with its own behavior layered on top of the three operating systems.

  • Driver – the translator between the PC/SC stack and the physical card reader. It converts PC/SC requests into USB packets that the hardware understands. Most of the world relies on the same universal CCID driver – the one maintained by Rousseau. More exotic hardware, such as racks with hundreds of card slots, usually requires its own driver and often communicates over a serial port.

  • Card commands – APDU instructions defined by ISO 7816-4. These are binary commands where 90 00 means success, while everything else represents one of dozens of possible ways to say "something went wrong." Those bytes are transported to the card over a lower-level protocol – T=0 or T=1 (defined by ISO 7816-3) – negotiated between the reader and the card before the very first APDU is exchanged.

So the stack looks like this: the application calls the language wrapper → the wrapper invokes the PC/SC API → the PC/SC stack talks to the driver → the driver (usually the universal CCID driver) communicates with the reader over USB → the reader communicates with the card using T=0 or T=1 (ISO 7816-3). The payload remains the same throughout the entire journey – an ISO 7816-4 APDU assembled at the top of the stack and delivered to the card's chip unchanged.

Hardware

  • Card reader hardware – anything from a single USB dongle holding one card to industrial racks capable of handling hundreds. Each has its own controller, its own firmware, and its own collection of quirks.

  • Contact interface – the final few millimeters of the journey: powering up the chip, reading the ATR (Answer To Reset – the card's "business card"), negotiating the T=0 or T=1 protocol, and agreeing on the communication speed as defined by ISO 7816-3.

From the outside, all of this looks like "launch the application and insert the card." Under the hood, it's a nine-layer stack, each layer with its own standard, its own timeouts, and its own unique ways to fail.

And that's only the first of the four abstractions.

Server

The server sits right in the middle of the chain – and it's the only place that has the full picture. To the tachograph, it looks like a remote company card. To the company card, it looks like the tachograph is plugged into the next slot. The only participant unaware of the substitution is the card itself. Under the hood, the server consists of three layers:

  • Vendor protocol parser – extracts APDUs from the tracker's proprietary protocol wrapper. Every vendor has its own format: some use binary packets, others plain text, some encode everything as Base64, and one vendor even encrypts the APDU while shuffling the byte order – so before you can do anything, you first have to put the bytes back where they belong.

  • Session orchestration – the state machine behind every authorization session: command queues, arbitration over which tracker currently owns a particular company card, and timeouts for every step. If a session stays silent for a minute, the server declares it dead and cleans it up.

  • Card transport protocol – the other end of the MQTT protocol used by the office application. Its job is to deliver an APDU to Tacho Bridge App, wait for the response, and wrap it back into the vendor-specific protocol. The transport protocol used to communicate with the card itself – T=0 or T=1 – is selected automatically by the application based on the card's ATR. From that point on, the server manages the session.

And this isn't about a single authorization. There are thousands of them running simultaneously, each with its own combination of tracker vendor, tachograph generation, and company card with its own personality.

Tracker

The tracker is the only participant in the chain that physically lives inside the truck, right next to the tachograph. On paper, its role is fairly modest: relay APDUs between the vehicle bus and the cellular network. In practice, every vendor does it differently.

  • Many vendors, many protocols. All proprietary and mutually incompatible: binary frames, ASCII strings, Base64 wrappers. Some trackers even establish a dedicated connection to the server for tachograph communication, separate from the main telemetry channel.

  • Obfuscation for no apparent reason. One vendor encrypts every APDU and swaps the first and last byte. Why? Only the vendor knows.

  • Pre-flight checks. Some firmware versions first ask the vehicle bus whether the tachograph is actually present before attempting authorization. Others don't. You find out only when they return an error.

  • Everyone plays by their own rules. On some trackers, the ignition being off means an immediate failure: the tachograph is there, the company card is ready, but the session won't even start. And every vendor has its own catalog of error codes – anywhere from 20 to 43 of them. Each code is more than just another log entry; it dictates what happens next: retry the command, wait and try again later, or terminate the session altogether. Six vendors mean six different decision tables, all hardcoded into the authorization logic. And for some vendors, the absence of any documented behavior turns out to be a behavior in itself, unfortunately.

Tachograph

The tachograph is the one that initiates the entire conversation. Unlike the company card, it knows exactly what's going on: remote authorization is an official operating mode defined by the regulations. Yet the dialogue it conducts is the same as if the card were inserted into its own slot.

  • Two manufacturers, three generations. Continental VDO and Stoneridge; Gen1, Gen2v1, and Gen2v2. Each generation comes with its own cryptography, so the very same operation looks different depending on the hardware generation.

  • It drives all four phases. Reading the card's identifiers, presenting certificates, verifying the card, establishing the secure channel – the tachograph initiates every step. The card simply responds.

  • Exceptionally generous timeouts. The regulations allow the tachograph up to an hour for a remote exchange and up to 24 hours for the entire session. The problem is that nothing else in the chain is willing to wait that long: every other component considers a minute of silence enough to declare the session dead.

  • The physical slot always wins. If a company, control, or workshop card is inserted into the tachograph, the remote session must be terminated – that's what the regulations require. Some tachographs don't bother distinguishing between card types and terminate the remote session whenever any card is inserted.

The chain: counting the links

Remember the "11 hops there, 11 hops back"? Here they are, one by one.

Tachograph. There are two major manufacturers on the market – Continental VDO and Stoneridge. There are also three generations: Gen1, Gen2v1, and Gen2v2, each with its own cryptography and data formats. The very same operation looks different depending on the generation.

Vehicle bus. CAN – the physical wires behind the truck's dashboard. Every message exchanged with the company card travels over the CAN bus. You may also find K-Line (pin D8) nearby, but that's a one-way channel: the tachograph only broadcasts driver activity data over it. Authorization traffic never goes there. And as for wiring... well, that's a story for another day.

Tracker. Firmware running its own proprietary tachograph protocol. We support many tracker vendors, which means many incompatible protocols. One of them, for reasons known only to its developers, encrypts every APDU and swaps the first and last byte. Why? Only the vendor knows. Maybe.

Cellular network. The truck keeps moving: cell towers change, roaming kicks in, latency fluctuates, connections drop. It's the only link in the chain that nobody else has any control over.

Flespi server. Internally, it consists of three layers: a vendor protocol parser (to extract APDUs from the tracker's wrapper), session orchestration, and the card transport protocol. Thousands of these sessions run simultaneously.

The Internet. The command leaves the cloud and heads back down to earth – over MQTT to the customer's office.

Application on the office computer. Windows, macOS, or Linux – three different smart card stacks, each with its own personality.

Card reader. It might be a simple USB reader with a single card, or an industrial rack holding hundreds of cards over a serial connection.

Card chip. The final centimeters of the journey. The chip itself responds in milliseconds. Virtually all of the latency comes from the ten links before it.

That makes 11 links in total (with the server itself consisting of three internal layers). Every one of them has its own timeouts, its own serialization rules, and its own unique ways to fail.

The parts that don't fit the model

Earlier, I mentioned that some devices don't use the standard PC/SC stack. A good example is custom hardware that communicates over a serial (COM) port. In practice, such devices implement their own proprietary protocol for talking to smart cards. A perfect example is the Lisle Design Rack – a card rack that can hold hundreds of cards, which we recently added support for. Its greatest strength is also its biggest weakness: its uniqueness. A custom protocol can be more convenient than the standard interface in some ways and less convenient in others – and whether you like it or not, you have to live with both.

The Lisle protocol is proprietary, so its implementation lives on the flespi server rather than inside the application. In this setup, Tacho Bridge App acts as a proxy: it discovers COM-port devices and forwards bytes between them and the server, while the server manages the entire process from the very first command to the very last.

Inside the application, this effectively becomes a parallel execution path. The rack operates alongside regular card readers but independently of them: failures in the rack don't affect PC/SC cards, failures in the PC/SC stack don't affect the rack, and authorizations continue uninterrupted for whichever side remains healthy.

Everything in this path is custom: its own orchestration, its own state machine, its own timeouts, and its own behavioral quirks. There is no off-the-shelf driver, no reusable stack, and no public documentation. You can't Google your way through it. All you have is the manufacturer's specification, conversations with the vendor, and plenty of experimentation with the actual hardware.

And the scale is very different, too. One COM port can serve hundreds of cards. If a regular USB reader fails, one card becomes unavailable. If the rack sneezes, hundreds of authorization sessions feel it simultaneously.

The trade-off is obvious: it's one more layer of complexity. It may sit off to the side of the main architecture, but it has to be maintained with the same level of care as every other part of the system.

The most fragile part

The secure channel has a counter. Every command increments it by one, and every response increments it by one again. The tachograph maintains its own counter, and so does the card. There's no way for them to compare the values directly: the counter is never transmitted. Instead, it's embedded in the cryptographic signature of every message.

Now imagine the following scenario.

A command reaches the card, but the response gets lost somewhere in a roaming network. The tachograph waits, times out, and retransmits the command. The problem is that the card has already advanced its counter, so the signatures no longer match. To the card, that retransmitted command is indistinguishable from a forgery. The secure channel is dead.

Roaming isn't the only thing that can kill a session. The company card is sitting in an office computer, and we're not the only application that can access it. All it takes is for another application to reset the card, and the session keys are gone; the counter is reset. The tachograph 3,000 kilometers away won't discover any of this until it sends the next command.

There's nothing to fix. There's nothing to negotiate. The only option is to start a brand-new authorization: all four phases, all 11 links, everything from scratch. A single lost packet can cost fifteen seconds of work across the entire chain.

And this isn't a flaw in the design – it is the design. The sequence counter is what makes the channel secure. A protocol that tolerated a lost packet would also have to tolerate a forged one. Cryptography is supposed to be paranoid, and paranoia is never forgiving.

The cost of it all

You can't debug authorization the way you debug ordinary code. There are no breakpoints: half of the chain consists of someone else's black boxes, and the other half is driving down a highway somewhere. All you have is a raw dump of a session that died last night, somewhere in the middle of a roaming network. Just reading that dump requires you to keep the tracker protocol, APDUs, ISO 7816, and the secure channel cryptography in your head at the same time. We ended up building a utility that decodes these dumps and breaks every session down into its individual phases. Without it, analyzing a single case would take hours – sometimes days. And there are plenty of cases.

The most expensive bugs are the ones you can't reproduce. A bug might appear in one out of every ten sessions, only with a particular firmware version and only on a specific network – nowhere else. Here, a test iteration isn't "rerun the test." It's "wait for the next real session from a real truck." You might deploy a fix today, but the only way to confirm it worked is by monitoring production statistics collected over the following weeks.

And here's the receipt.

Across roughly 50,600 tachograph-enabled devices and six different protocols, we recorded 17 unique tachograph-related errors in a single month. That number didn't come from a specification. Behind every one of those errors are hours of debugging on real hardware, conversations with vendors, and knowledge that exists nowhere in the documentation.

The complexity never went away. It was just paid for in advance. And it's never a one-time payment: a new firmware release, a new tachograph generation, or a new tracker arrives – and the bill shows up all over again.

What's next

Not a single link in this chain was built by the same team as the one next to it. The tachograph comes from one company, the tracker from another, the smart card stack from a third, and the regulations from the European Commission. When something breaks at the boundary between them, everyone looks at their own piece and honestly says, "Everything works on my side." The one who ends up fixing it is the one who sits in the middle.

What exactly breaks is the topic of the next part.

Spoiler: the most reliable tachograph manufacturer on the market is perfectly capable of returning garbage with a success status, and sometimes the server has to append bytes to someone else's commands just to keep the conversation going.

So, the story is to be continued…