/solid

An OIDC authorization server building blocks with security and privacy by design philosophy.

Primary LanguageGoApache License 2.0Apache-2.0

SolID

An OIDC authorization server building blocks with security and privacy by design philosophy.

This will not provide a full-featured standalone OIDC Server but a limited and secure settings according to your use cases :

  • online users using authorization_code flow with mandatory PKCE via Pushed Authorization Request with state enforcement;
  • machine-to-machine using client_credentials based on asymetric authentication schemes;
  • devices and constrained environments, you know for IO(v)T (Internet Of vulnerable Thing);
  • offline users using refresh_token flow for application that need to act as an online user but without its online interaction.
  • impersonation / delegation using token_exchange flow fro resource server who wants to access authenticated external resource on behalf of the subject with a restricted resource level privilege set.

What and Why

I have been developing OAuth/OIDC/UMA providers since 2012, in multiple languages and environments. People generally don't understand OIDC flows.

It's like driving a car that requires you to know how engine work and how the car is built. But the only thing you want is to drive your car.

OAuth / OIDC is often criticized in favor of SAML, but implementations are more vulnerables than the protocol itself. OAuth is just offered as a developer framework, but it's true to say that not all developers are aware of security problems.

Implementations are done by developers that don't have/take the time to browse the specification maze, they read them quickly with their own belief in mind. As a consequence the specifications are not understood but barely interpreted, that will produce faulty implementations.

Also security products are often associated with NIH syndrom.

What I observed in real life:

  • Not using authorization_code because it doesn't have user/password in the flow;
  • client_credentials grant type to be used as customer credentials like password grant type but for external customer user access (login form with client credentials);
  • Using client_credentials from a JS public UI (hardcoded client_secret);
  • Dynamic authorization application based on token claims without signature checks;
  • Authentication based on the fact the you can retrieve the token ... not validating token content (Token is here => You are admin);

Many OIDC providers give you a lot of features that you have to understand and choose to maximize your security posture. So that your security posture is correlated to your understanding of OAuth and OIDC and their implementations in the product.

I don't like this idea to be honest.

I understand the requirements of commercial products to have a wide compatibility matrix, but by allowing insecure settings for one client you can compromise the the whole platform, and also lose the customer inside the feature fog.

But OAuth / OIDC specification are only tools in a toolbox, and they need to be orchestrated in a proper way to provide a simple, efficient and secure service.

That's the reason why I've started this project as an OSS project, to provide a simple and solid implementations of 4 OAuth flows.

Objectives

  • Enforce OIDC features as a complete suite according to selected use-case;
  • Provide a complete toolchain to enforce security and privacy without the complete knowledge of all related protocols;
  • Enhance security posture based on security objectives not the understand of security protocols;
  • Provide a battle-tested framework;
  • Provide a wire protocol decoupled framework, OIDC is tighly coupled to HTTP but it can be easily decoupled to become portable between other wire protocols (CoAP);

What is not

  • A complete OIDC compliant server. By making some optional and recommended parameters as required, solid can't pass the OIDC compliance tests;

Getting started

I made sample server and various integrations inside examples/ folder.

Features

Protocol changes

  • PAR+DPoP+JARM is enabled and enforced for authorization_code flow;
  • hybrid flow is not and will be supported; Web applications must use server side component (or lambda) to negociate authorizations; By design, your client-side application code (JS) should not be exposed until you are identified;
  • Only response_type code will be supported to enforce server-side negociation;
  • PKCE+Nonce is enforced by default for all client types during authorization_code flow;
  • authorization_code flow could not be started by the user-agent, as the default behavior, the client must use PAR protocol to retrieve a request_uri that will qualify and start the authorization_code flow;
  • Asymetric authentication methods are enforced by default;
  • No HSxxx / RSxxx support as JOSE signature algorithms;
    • HSxxx doesn't provide digital signature;
    • RSxxx uses RSA algorithms that needs to have high computation to improve security protection level so that it will be more difficult for constrained environment (IoT) to have same security protection level as a normal application;
    • Only elliptical curves involved algorithms will be used;
  • access_token / refresh_token are hybrid tokens so that they embed protocol validation details (expiration, etc.) without any privacy related info (sub). These informations are referenced via an embeded jti claim that will address an AS-only accessbile record that will contains extra data;
  • audience parameter is mandatory for request that need scope in order to target the corresponding application. This will allow various validations between client and application, and consent management;
  • PAR must use JWT encoded request payload to due request registration.

Framework

Integrations

  • HTTP
    • Authorization Server
      • Standalone
      • Caddy plugin
    • Reverse Proxy
      • Caddy plugin
  • CoAP
    • Authorization Server
      • Standalone
  • AWS
    • Auhtorization Server
      • AWS Lambda

References