Tagging and Metrics - zwettemaan/TightenerDocs GitHub Wiki

Tightener provides infrastructure that allows a developer to have control over how their software is used.

The Tightener infrastructure can be used to build trackers, licensing systems, activation systems, usage counters...

Tightener itself is not directly handling any of these functions.

It merely provides the necessary APIs and tools to implement such functions.

Things like payments, activation codes,... are not handled by Tightener, and the developer remains in full control of their implementation.


Tightener will use GUIDs to tag all kinds of components of the system, and will track the relations between these components.

Tightener Repository

To accomplish this, there is a centralized Tightener Repository on the internet.

In order to reduce the attack surface available to hackers, this repository does not contain any useful data.

All it stores are hashes/GUIDs, dates, and validity states.

The repo can verify that a certain hash is present in the repository, what it's state value is, and when it was added to the repo, and when it was last accessed.

Hashes table: hash (guid string), state (int), last access date (date), date added (date)

state = 1: valid state = 0: invalid

Public keys: the repo also contains public keys, keyed by a user hash


An simplified example for clarification:

Instead of using a full name (e.g. 'Kris Coppieters') we calculate a salted, GUID-like hash.

The salt value is itself a hash, derived from a secret user password, retained by the user, not communicated to the Tightener repository.

A hash cannot be reversed; it's a one-way mechanism.

  • Given the full name and user password we can immediately calculate the hash.
  • Given the hash, it is computationally infeasible to recover the associated name or the password

Because the hash is salted, even a dictionary lookup with a list of full user names does not work: a hacker would need a matching table of per-user salts in order to perform a dictionary lookup.

Individual computers and virtual machines get semi-permanent GUIDs assigned to them by Tightener.

The Tightener repository registers the relation between the user and the computer by storing a hash of the concatenation (computer GUID + user name hash) in the repository.

That way, we can quickly verify that a particular user is associated with a particular computer, without ever storing the user's name or the computer GUID.

Such verification would be triggered from the computer in question, while the user is there to provide the password.

That computer can calculate the hash value and then query the repository to see whether that hash exists in the repository.

We cannot scan or list out the table and get an overview of users and computers because the Tightener repository does not contain enough info to figure out any user names or computer GUIDs.

Computer GUIDs

Once a GUID is associated with a certain computer or virtual machine it remains associated with that computer forever.

The reverse is not true: one particular computer will get more than one GUID associated with it as time passes.

Only one of those GUIDs is 'current' - all other GUIDs are invalid.

They remain associated with the machine (so we know that the machine was tied to a particular GUID in the past), but are seens as 'previous GUID, now invalid'.

Tightener will assign a random GUID to a new computer or virtual machine and register this GUID into the Tightener repository.

localStateHash = hash(local situation data: user name, Ethernet card address, IP address, location data,...)

The idea is that localStateHash is somewhat 'brittle' and changes if there is an indication the machine might not be the same machine any more (e.g. virtual clone: if the IP address changes, the GUID changes).

LOCAL: curGUID lastPingDate

REPO: hash(curGUID + localStateHash), lastPingDate

If a computer already has a GUID, Tightener will occasionally verify this GUID: calculate the hash(curGUID + localStateHash) and ping the repo.

Things that might happen:

Computer changes, so localStateHash changes -> pinging the repo fails.

Computer is cloned -> two machines will have the same GUID. They might still retain the same localStateHash.

Computer A consults the repo and pings the curGUID with the lastPingDate.

If curGUID is not registered, the repo tells computer A the GUID is invalid.

If the lastPingDate does not match, the repo invalidates the GUID (state = 0), and tells computer A the GUID is invalid.

If lastPingDate does match, the repo updates the lastPingDate and returns the info back to Computer A. Computer A registers the updated lastPingDate from the repo. The GUID is valid

If the GUID was invalid, a new GUID is created and registered with the repo.

Capability files

Signed JSON file, plain text. This file is human readable, but provable valid because it contains a signature that can be verified against the signer's public key.