⏱ Estimated reading time: 12 minutes

Table of Contents

Randomness: exploring how everything happens for a reason

By Théo Gillet, Frontend Engineer @ ekino

Randomness happens when the result of an action cannot be determined with certainty. A dice throw could be deterministic if all of the parameters of the throw are perfectly controlled. Casinos, for instance, drill and fill dice to guarantee that results are uniformly distributed. Randomness is essential, as it helps eliminate biases. It’s used for designating court jury participants, enabling cryptography, online games and games in general.”Serendipity” itself is a happy accident due to random chance.

Given this, can a computer produce randomness? Not really, since computer are essentially deterministic.

Pseudo-randomness

Pseudo Random Number Generators (PRNG) are programs that generate lists of numbers that look random using a provided initialization number called a seed. Like in Minecraft where the same seed procudes the same world, initializing a PRNG with the same seed would output the same sequence of numbers.

John von Neumann’s middle-square method is one example of PRNG. The method is simple but only works for numbers with an even digit count: square the chosen number, add zeroes in front of the square to reach double the digit count of the initial number, read as many middle digits in the square as there are in the initial number.

Example:

  • Initial number: 1234, 4 digits
  • Square: 1234 ^ 2 = 1 522 756
  • Add zeroes to reach 2 * 4 = 8 digits: 01 522 756
  • Select 4 middle digits: 01 5227 56
  • Final number: 5227

These algorithms come with a major flaw: they repeat after a while and can become predictable after having observed enough iterations.

True randomness

Entropy is a unitless measure of chaos. You cannot describe the complexity of a password in how many “entropies” it contains, but you can estimate it based on how many possibilities there are. XKCD 936: Password Strength is one example of this phenomenon. Reaching “true” randomness would require sources of information that are hard to predict such as atmospheric noise, quantum events, lava lamps, etc.

See Cloudflare’s League of Entropy for an initiative around a true source of randomness.

Most programming languages come with an implementation of a random number generator. Most will use operating system APIs to feed the generator while the most advanced will use data gathered from external peripherals such as keyboards and mice.

If you need a secure way to generate random numbers for a project, check out Cryptographically Secure Pseudo Random Number Generators (CSPRNG).

Welcome to the wonderful world of tokens!

By Richard Boilley, Backend Engineer @ ekino

The world before

Let’s go back to the Internet of 2008. At the time, Yelp suggested their users to grant access to their contact list to the app by giving the app the credentials of their email address. This shocking practice was the only way an app could retrieve information stored in a different app, then. It was however understood that there was no way to limit the scope of permissions, easily revoke access and requires credentials to be stored in plain text! Security was clearly not the priority during those times.

Due to the growing interconnectedness of the web, something was needed. A standard that can authenticate users and grant permissions for a given scope and amount of time. In old English, “tācn” designated an object that would represent something else. This term is now better known as “token”.

Before coming up with a standard, each web platform created their proprietary solution. In 2007, Blaine Cook, then lead developer at Twitter started writing an open specification for access delegation. In 2010, OAuth v1 was announced, then came OAuth v2 in 2012. The latest version, OAuth v2.1 is currently in Draft and slated for release in 2026.

OAuth 2.0

This standard specifies four entity types:

  • Resource Owners: usually end users;
  • Resource Servers: backend handling the end user data;
  • Clients: apps provind services to end users;
  • Authorization Servers: trusted third party delivering permissions.

The common flow to access a resource then goes like this:

  • Resource Owner uses Client to access Resource Server;
  • Resource Server returns an error to Client requesting a valid authorization token;
  • Client requests a token to Authorization Server that would grant the permissions required to access the resources accessed by Resource Owner;
  • Authorization Server requests that the Resource Owner be redirected to a consent screen so that they can register their consent for the first time;
  • Resource Owner is redirected to said screen and consents to their data being accessed by Client for the given purpose. They consent;
  • Resource Owner hands the resulting token to Client, which they use in their new request to Resource Server;
  • Resource Server returns the requested data, Client app can proceed.

This protocol is flexible enough so that Clients can request a minimal amount of resources for a limited time. Access revocation is possible from the Resource Server.

Because there are plenty of topologies of apps and devices, there are many ways in which one can get authorized to access a resource in a Resource Server. Auth0 lists and describes them in their documentation. In short:

  • Authorization Code: common scenario where a Client gives a code to the Authorization Server against a valid token;
  • Client Credentials: service-to-service scenarios implicating no user, like scheduled tasks;
  • Device Code: for the Internet of Things devices that can access the Internet but are input constrained. A different device authenticate for them;
  • Resource Owner Password: for the extreme case where the user cannot be redirected to a consent screen.

Further details about Auth

Though this talk we have been talking about Authorization (AuthZ), but there is a different type of auth called Authentication (AuthN). This is not an oversight: OAuth is a protocol that specifies access to a resource but does not prove any information about the principal other than their technical identifier. If you are looking to replace a login screen with a centralized solution that delivers authentic information about the user, then you are looking for OpenID Connect, which extends OAuth 2.0 and adds the authentication protocol developed in OpenID.

OpenID, like OAuth2, uses tokens too. These tokens are usually in the Json Web Token (JWT) format, though you may find Opaque Tokens at times. JWTs appear under the form of a string containing three base64 encoded sections separated with a period . character. It is composed of:

  • A Header, which describes the algorithm and the key that has been used to sign the token;
  • A Payload, which contains the token information also known as “claims”;
  • A Signature, which applies the algorithm and key described in the Header to the Header and Body.

While the most important part of a JWT is its Payload, the Signature is what makes it verifiable and authentic. The token contains all the information an app should need to prove who the Resource Owner is or grant Clients access to resources.

On the subject of OIDC, this protocol describes three types of tokens:

  • Identity, to prove the Resource Owner’s identity;
  • Access, to grant access to the Resource Owner’s resources;
  • Refresh, to renew Access tokens before their expiration date. This is how some websites keep you securely logged in for months!

Questions and Answers

Can I prove the identity of a user without granting them any access?

If you are talking about OIDC, you could request that a Client gives you a token with no scope. This would mean that the user went through a login screen, then a consent screen that requested basic user information and no resource access.

How does this work with Single-Sign-On SSO services?

The sequencing of the flow gets more complex with the introduction of one or multiple Identity Providers (IdP) invoked through the same or a different protocol like Secure Assertion Markup Language (SAML). Basically, when the user is faced with the Authentication and Authorization Server —since we are speaking of OIDC here— and have no active session, they would be redirected to their Identity Provider through their configured protocol, then back to their Authorization Server which would grant them their tokens in case the SSO authentication succeeded.

What would happen when a user gets compromised?

Indeed, per their claims, tokens are valid until their expiration date, which is a problem when a user gets compromised! Short Access token expirations can help, but a definitive solution involves detecting the fraud and revocating tokens in the Resource Server code.

Intro to non-technical debt

By Florian Kauder, Expert Backend Engineer @ ekino

Technical debt

Similarly to a financial debt for an organization, technical debt is contracted when technical teams decide to clean up later and take shortcuts to deliver later. Of course, clean up has to be done eventually… or so we believe.

The concept of technical debt has been introduced in 1974 by Manny Lehban through their second law of software evolution:

“Increasing Complexity”: as [a system evolves with its real-world model], its complexity increases unless explicit work is done to maintain or reduce it.

In 1993, Ward Cunningham, then a developer for an Enterprise Resource Planning software for the financial industry, wanted to explain to their non-technical boss in terms they could understand why they had a need for refactoring some of their code. There was born the earliest known use of the term “technical debt”.

Evolution into non-technical debts

Research into technical debt did not start until much later; the first research papers that covered the subject were published circa 2009! Other types of debt were defined. We are labeling them as “non-technical debts” for simplicity. They can be split into three groups:

  • Purely technical: architecture, tests, design;
  • Business: prerequisites, requirements documentation;
  • Productivity: build, tooling.

Debts can also be classified by impact: personal, social, processes, organizational. These aspects are being explored by research teams. To understand them: each individual has specific behaviors and skills (personal debts), they have interactions with their team (social debts) and they receive work from and report to their superiors (process debts) and they are part of a more complex environment and organization (organizational debts).

Recommended read: Non-technical debt in Agile software development, by Muhammed Ovais Ahmad and Tomas Gustavsson

Here are two situational examples to help define and classify debt and its impact:

  1. Your team puts up with long meetings that regularly spill over following meetings, mandanting members to cancel meetings and move work around.
    • This is an example of Process debt;
    • Issues are caused by missing potentially critical information, leading to less information sharing, continuous improvement, learning from failure and leading to frustration.
  2. Some developer only gives a team member easy tasks, even though their skill sets are similar.
    • This is an example of Social debt;
    • This behavior shows biases which lead to losses of trust and reduce psychological safety in the team.

For a more taxonomical view of nno-technical debts, read The Pandora’s Box of social, process and people debts in software enginnering, by Muhammed Ovais Ahmad and Tomas Gustavsson