Skip to main content

Tutorial: Build a TideCloak + Next.js App from Scratch

Scaffold a fresh Next.js app wired to TideCloak, with auth, middleware, and optional QEA (Quorum Enforced Authorization) - in minutes.

1) Prerequisites​

  • A TideCloak server you manage (dev or hosted). For dev, you can run the Docker image locally.
  • Node.js 20.9 or later (required by Next.js 16, which the template uses)
  • curl and jq, used by the initializer

2) Initialize the template project​

The initializer can create the realm and clients on your TideCloak server (including Tide Realm Admin creation and QEA enablement).

Install curl and jq if you don't have them (Debian/Ubuntu example):

sudo apt update && sudo apt install -y curl jq

Run the initializer and answer its prompts. The defaults work for a local dev server; choose TypeScript to get the files shown below.

npm init @tidecloak/nextjs@latest my-app

Complete Tide enrolment when the initializer asks​

Once the prompts are answered, the initializer creates the realm and generates the app, then stops and prints a line like this:

ACTION REQUIRED: Open this URL and complete Tide enrollment: https://...

That link sets up the Tide account for your realm's first admin. Open it, finish enrolment in the Tide enclave, and leave the initializer running. It polls for the new account and finishes on its own once enrolment lands. The enclave step can take a few minutes.

note

Until enrolment completes there is no first admin, so the realm is unfinished and the app has nothing working to start against.

Project structure (generated)​

my-app/
├── app/
│ ├── api/
│ │ └── protected/
│ │ └── route.ts
│ ├── auth/
│ │ └── redirect/
│ │ └── page.tsx
│ ├── home/
│ │ └── page.tsx
│ ├── tide_dpop/
│ │ └── [...path]/
│ │ └── route.ts
│ ├── layout.tsx
│ └── page.tsx
├── init/
│ ├── realm.json
│ └── tcinit.sh
├── public/
│ ├── silent-check-sso.html
│ └── tide_dpop_auth.html
├── middleware.ts
├── next.config.js
├── package.json
├── tidecloak.json
└── tsconfig.json
  • app/page.tsx: login page
  • app/home/page.tsx: landing page after login, with an encrypted note and a Verify Token button
  • app/auth/redirect/page.tsx: redirect target after login and logout
  • app/api/protected/route.ts: API route that verifies the access token
  • app/tide_dpop/[...path]/route.ts: serves public/tide_dpop_auth.html with the headers Tide's DPoP flow needs
  • middleware.ts: verifies the token on /protected routes. Next.js 16 warns that the middleware file convention is deprecated in favour of proxy; the app still builds and runs.
  • tidecloak.json: your adapter config, written by the initializer
  • init/: the realm template and script the initializer runs. Run npm run init to run it again later.

The JavaScript template has the same layout with .jsx and .js files.

3) Run the app​

cd my-app
npm install
npm run dev

Open http://localhost:3000. You should see the Welcome! login page.

Expanding from the template

Implementing encryption/decryption​

The template's realm already grants every user the _tide_message.selfencrypt and _tide_message.selfdecrypt roles, which app/home/page.tsx uses to encrypt and decrypt a note. To encrypt data under other tags, first set up encrypt/decrypt roles for them.

TideCloak lets you protect sensitive fields with tag-based encryption. Pass in an array of { data, tags } objects and receive encrypted strings (or vice versa).

Syntax Overview​

// Encrypt payloads:
const encryptedArray = await doEncrypt([
{ data: /* string */, tags: ['tag1', 'tag2'] },
// ...
]);
// Decrypt blobs:
const decryptedArray = await doDecrypt([
{ encrypted: /* string from doEncrypt */, tags: ['tag1', 'tag2'] },
// ...
]);

Order guarantee: the returned array matches the input order.

  • Encryption requires access token roles _tide_<tag>.selfencrypt for each tag.
  • Decryption requires access token roles _tide_<tag>.selfdecrypt for each tag.