So, you want to build the best digital platforms on the planet, without the burden of worrying about security, and simultaneously grant your users sovereignty over their identities? Great!
This example repo demonstrates the minimal steps required to secure a web-based platform utilizing NextJS and TideCloak - all in under 10 minutes .
TideCloak gives you a plug and play tool that incorporates all the concepts and technology discussed in this series. It allows you to manage your web users' roles and permissions - It's an adaptation of Redhat's open-source Keycloak, one of the most robust, powerful and feature-rich Identity and Access Management system. But best of all it's secured by Tide's Cybersecurity Fabric so no-one holds the keys to the kingdom.
If you've done this before, or know well what you're doing, you can skip this guide and just follow the summarised steps:
git clone https://github.com/tide-foundation/tidecloak-client-nextJS.git
cd tidecloak-client-nextJS
sudo docker run \
-d \
-v .:/opt/keycloak/data/h2 \
-v ./test-realm.json:/opt/keycloak/data/import/test-realm.json \
--name tidecloak \
-p 8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=password \
tideorg/tidecloak-dev:latest
npm install
Activate license by Manage License then Request License
.
Get settings by Clients → myclient → Action → Download adapter config
and put it inside tidecloak.json
.
npm run dev
Enable IGA
And play!
Otherwise, follow this guide below:
Before starting, make sure you have:
- Docker installed and running on your machine
- NPM installed
- Optional: Git installed
- Internet connectivity
For the purpose of this guide, we assume Debian Linux command syntax (either under Windows WSL or not).
- Download and stage the Next.js project structure first. One way is by cloning this repository:
git clone https://github.com/tide-foundation/tidecloak-client-nextJS.git
Although there are other ways too.
This can also be done by either:
- Downloading and unzipping this repository from https://github.com/tide-foundation/tidecloak-client-nextJS/archive/refs/heads/main.zip
- Creating each file from scratch.
- Set yourself at the root of the project directory. e.g.:
cd tidecloak-client-nextJS
TideCloak can be deployed locally, you can host it, or you can have a fully managed instance on SkyCloak. In this guide, we'll show you how to deploy a dev-mode docker instance locally. Start a TideCloak-Dev docker container that already includes all the basic configuration and settings to get you going. To get it, open your Docker/WSL/Linux terminal and run the following command from the root folder of this project (where test-realm.json is):
sudo docker run \
-d \
-v .:/opt/keycloak/data/h2 \
-v ./test-realm.json:/opt/keycloak/data/import/test-realm.json \
--name tidecloak \
-p 8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin \
-e KC_BOOTSTRAP_ADMIN_PASSWORD=password \
tideorg/tidecloak-dev:latest
This may take a couple of minutes, so be patient. When it's done, you'll be able to go to TideCloak's console at: http://localhost:8080
Your realms has been automatically imported and set up.
This is how it was set up:
- Create a new Realm
nextjs-test
. - Set up a Tide IdP:
Identity providers
menu →Tide
social provider →Settings
tab
- You can upload a custom background image and/or custom logo image for your users' Tide login page.
- Verify user registration (good practice for production environments) is off:
Realm settings
menu →Login
tab →User registration
set toOff
- Remove the user detail collection:
Realm settings
menu →User profile
tab → DeletelastName
, DeletefirstName
,email
→Required field
set toOff
→Save
- Enable Tide IdP in authentication flow:
Authentication
menu →Flows
tab →browser
flow →Settings
ofIdentity Provider Redirector
→Alias
set to "tide",Default identity Provider
set to "tide" →Save
- Activate Tide linking:
Authentication
menu →Required actions
tab →Link Tide Account
enable toOn
- Create client:
Clients
menu →Clients list
tab →Create client
button →Client ID
set to "myclient",Next
→Authentication flow
tick onlyStandard flow
,Next
→Valid redirect URIs
set tohttp://localhost:3000/silent-check-sso.html
andhttp://localhost:3000/auth/redirect
,Web origins
set tohttp://localhost:3000
(NO '/' AT THE END!),Next
- Add roles to JWT:
Clients
menu →myclient
client ID →Client scopes
tab →myclient-dedicated
scope →Scope
tab →Full scope allowed
set toOn
- Create self-encryption roles:
Realm Roles
menu →Create role
button → setRole name
to "_tide_dob.selfdecrypt" →Save
Realm Roles
menu →Create role
button → setRole name
to "_tide_dob.selfencrypt" →Save
- Add new roles to default roles:
Realm settings
menu →User registration
tab →Assign role
button →Filter by realm roles
dropdown → tick both new roles →Assign
To hook your TideCloak host into Tide's Cybersecurity Fabric, you'll need to activate your license. Tide offers free developer license for up to 100 users. To do that, you'll need to:
- Navigate to your TideCloak administration console at the Tide IdP Settings page
- Log in using your admin credentials (Username:
admin
, Password:password
, if you haven't changed it) (You should be automatically navigated to:nextjs-test
realm →Identity Providers
menu →tide
IdP →Settings
tab) - Click on the
Manage License
button next toLicense
- Click on the blue
Request License
button - Go through the checkout process by providing a contact email
Within few seconds, you'll get your TideCloak host licenced and activated!
To secure your realm against the highest cyber-threat, compromised-insider, set up provable Identity Governance and Administration on your realm (IGA for short). This step will achieve two important goals: protecting the realm's authority key with Ineffable Cryptography (where no one will ever hold), and restrict changes to only ones approved by a quorum of Tide-protected admins. For a complete step-by-step guide on setting it up securely, read here.
For a quick-guide, follow these steps:
- Realm settings menu → General → Identity Governance and Administration : On
- Users menu → Create new user → Username: alice , Email: alice@email.here →
Create
- Users menu → alice user → Credentials tab →
Credential Reset
link → Reset action : Link Tide Account →Copy Link
button - Paste the link in a new (or private) browser and follow the instructions on screen to associate an existing or a new Tide account to Alice's account. Once associated, close that browser when done.
- Return to the realm administration: Users menu → alice user → Role Mapping tab → Assign Role → tide-realm-admin :
Assign
- Change Requests menu → Users tab → tick Granting Role to User (tide-realm-admin) →
Review Draft
- Tick same role again →
Commit Draft
From this point on, the original TideCloak admin has no longer authority in the nextjs-test, and from now on, all administration and provisioning in that realm should be done exclusively as Alice, through the realm direct administration console.
- Open another new (or private) browser here and use Alice's Tide account to log in.
- Change Requests menu → Clients tab → tick New Client Created (myclient) →
Review Draft
- Tick same client again →
Commit Draft
Export your specific TideCloak settings and hardcode it in your project:
- Go to your Clients menu →
myclient
client ID →Action
dropdown →Download adaptor configs
option (keep it askeycloak-oidc-keycloak-json
format) - Download or copy the details of that config and paste it in the project's root folder under
tidecloak.json
.
For this example project's purpose, you'll need at least one "standard" user that is allowed in. As the newly appointed realm admin, Alice, set up Bob as a "standard" user:
- Users menu → Add User → Username: bob , Email: bob@email.here →
Create
- Users menu → bob user → Credentials tab →
Credential Reset
link → Reset action : Link Tide Account →Copy Link
button - Paste the link in a new (or private) browser and follow the instructions on screen to associate an existing or a new Tide account to Bob's account. Do not associate Alice's Tide account for Bob! Once associated, close that browser when done.
-
Install all the NodeJS dependencies for this project (you only need to do this once):
npm install
-
Build and run your project for debugging:
npm run dev
Alternatively, you can set up the project for production.
-
To build and stage the project, use this instead:
npm run build
-
Then run in production:
npm start
- Go to http://localhost:3000 You should see a welcome message to your app.
- Click on the
Login
button - Use Bob's Tide account to log in
- Once successfully signed in successfully, you'll land in the "Protected Page" showing you your anonymized username and confirming you have been assigned a UMA role (that's just a random role assigned to everyone we chose for this demo).
- You can now click on
Make API Call
button to invoke a backend request to retrieve protected information. - Once pressed, you'll get the JSON content of the API response displayed.
- You can also access the protected personal data page by clicking on its link. Here, you can experiment with Tide's End-to-End Encryption (E2EE) to lock and unlock the Date-of-birth (DoB) field, that no one can access except Bob.
- You can also press the
Logout
button to invoke a full Single-Sign-Out.
Let's review what just happened and what you've just accomplished:
- You have built and deployed, from the ground-up, a fully-functional Next.JS full-stack app - both front end and back end.
- Web users, like Bob, can be invited by admins, like Alice, to use it securely with their Tide account. Your web users enjoy provably-secure Tide accounts, with their identity and access-credentials sitting outside of anyone's reach.
- Your web users can sign in to your app, be served customized content to authenticated and unauthenticated users and based on their predefined roles.
- Your web users' roles and permissions are managed locally on your very own self-hosted instance of TideCloak - one of the most robust, powerful and feature-rich Identity and Access Management system which you have downloaded, installed, configured and deployed locally.
- Your TideCloak realm ("nextjs-test") is secured by the global Tide Cybersecurity Fabric that you have activated and licensed.
- Your realm's authority key, the VVK, is secured, out of anyone's reach, by Tide Cybersecurity Fabric, such that even if your administrators, your TideCloak's instance, its source code or even our staff at Tide get compromised, still no one can ever get a hold of it.
- Changes to the realm's users access rights (e.g. roles, settings, clients) can be drafted by any of the realm's Tide-secured admins, but only go into affect after the rightful quorum of admins reviewed, agreed and committed it. No one can manipulate or bypass that process.
- Your web users sensitive date-of-birth field is hermetically secure at rest and in transit, by a key that is literally out of anyone's reach (Including administrators. Including us), and is unlocked only to the authorized users (themselves) at the edge device, on their browser.
For our supported access to these capabilities, sign up to our free Beta Program
The Next.js project structure:
tidecloak-client-nextJS/
├── public/
│ └── silent-check-sso.html
├── lib/
│ ├── db.js
│ ├── IAMService.js
│ └── tideJWT.js
├── pages/
│ ├── index.js
│ ├── fail.js
│ ├── protected.js
│ ├── api/
│ | ├── retrieve.js
│ | ├── store.js
│ │ └── endpoint.js
│ └── auth/
│ └── redirect.js
├── middleware.js
├── keycloak.json
├── keys.json
└── package.json
Here's the process happening on a successful access request:
- User opens the default homepage at http://localhost:3000 (served by
index.js
) and presses theLogin
button. - The page initializes a TideCloak session and calls for a log-in process. The user's browser is then redirected to TideCloak.
- TideCloak redirects the user to Tide as an external IdP (Identity Social Provider).
- Tide presents the user with its secure-enclave to conclude a sign-up / sign-in process.
- The user performs a zero-knowledge registration and authentication with Tide.
- Once successfully creating / authenticating the user with hermetic anonymity, together with secure authorization information managed on TideCloak, Tide creates and signs the user tokens to be sent back.
- The
redirect.js
callback page, exchanges the user's authentication code with the user tokens and redirects the user to be validated by the backend. - Once the
middleware.js
backend validates the tokens and the specific user's roles in the context of this session, it redirects the user to its final secure destination. - The
pretected.js
renders only for the authenticated and authorised user. From this point onwards, the user's token will follow every page they go, where the middleware will recheck before rendering the protected content on the browser.
If the user still holds a valid access token, by a previous session or through a Single-Sign-On on a different, related client (web platform), the system will automatically recognize it and redirect the user to its destination, skipping the unnecessary sign-in process.
- User opens the default homepage at http://localhost:3000 (served by
index.js
). - The page initializes a TideCloak session (in a hidden frame
silent-check-sso.html
) that performs a background check against TideCloak. - If TideCloak recognizes that user to be already signed-in, it'll provide the necessary code required for authentication.
- Once confirmed as authenticated, the
index.js
page will automatically redirect the user to be routed as authenticated. - The
redirect.js
page will initialize the access tokens in the session and redirect the user to the backend for validation. - Once the
middleware.js
backend validates the tokens and the specific user's roles in the context of this session, it redirects the user to its final secure destination. - The
pretected.js
renders only for the authenticated and authorised user. From this point onwards, the user's token will follow every page they go, where the middleware will recheck before rendering the protected content on the browser.
When a user fails to successfully authenticate, it will be redirected back to the original home page on index.js
.
A successfully authenticated user that have been assigned roles / permissions / privileges that are insufficient for the pages / section of the web site will be redirected to the fail.js
page where they could sign out
.
While on a protected page (e.g. protected.js
) the frontend may initiate manual or automated API requests from the backend that require the specific user's credentials.
During a normally authorized session, the user may opt to leave, but with explicit request to sign themselves out. This will trigger a system-wide sign-out process that will impact their sessions across other related-platforms as well.
To guarantee the user remains connected and properly served while preventing a malicious actor from stealing that user's session, there's a background mechanism happening that continiously checks the session liveness and extends it.
Although it's not mandatory, it is assumed that end-to-end-encryption (E2EE) flows are served from a protected page. This code example, that is showcasing a standard scenario to decrypt a sensitive user Date-of-Birth field in a form, protects access to the form as described above on how to protect protected.js
page: navigating with a valid JWT as a bearer token and validating the JWT in back-end's middleware.js
script. Without these, the page wouldn't even load.
The E2EE flow only starts from that point:
- User requests to load the dob.js form.
- The
dob.js
form is loaded and the date-of-birth field is being requested from theretrieve.js
endpoint at the backend. That request bears the user's access token. - The backend validates the user's JWT to assure the user has the correct
_tide_dob.selfdecrypt
role associated. If so, a request to the database is made to retrieve that field in it's encrypted form. IMPORTANT TO NOTE: neither the database nor the backend script have the key to decrypt that field! - The field is being sent to the frontend, still in its encrypted form.
- The frontend sends that encrypted field to the user-interface.
- The script on the user-agent (browser) performs a request to the swarm in Tide Security Fabric that is responsible for that authority key, using a similar (but not identical) access token.
- Each Tide node in that authority key's swarm performs a validation of the access token, making sure that Tide-authenticated user-session holds a cryptographically-assured access roles for this particular field - and if so, performs a multi-party decryption on that field. The garbled replies from all the swarm's nodes are being interpolated on the user's browser to finalize the decryption process, and present the date-of-birth clear-text field for the user.
- Once a user made a change in the Tide-defined sensitive field, the date-of-birth, the user-agent browser communicates with the authority's keys swarm.
- Each of the swarm nodes performs validation of the user and the field and to finalize the authenticated-encryption of that field before sending it back.
- Once encrypted, the form is posted to the backend, as a standard HTTP POST request, with the date-of-birth field encrypted.
- The form details are being sent to the backend, where it all being validated.
- Once validated, the backend stores the field in the database in its encrypted form - with no key stored in the system.