diff --git a/adr/v4/.gitkeep b/adr/v4/.gitkeep
new file mode 100644
index 000000000..e69de29bb
diff --git a/adr/v4/authentication.md b/adr/v4/authentication.md
new file mode 100644
index 000000000..41a0ff71b
--- /dev/null
+++ b/adr/v4/authentication.md
@@ -0,0 +1,15 @@
+# Authentication
+
+## Basic
+
+Standard
+
+## LDAP
+
+Standard
+
+## OIDC
+
+New: We want to provide generic OIDC support, so users can use any OIDC provider.
+For test purposes, Authentik seems to be a reasonable choice, for a real-world scenario, it might be a good idea to test it with GitHub.
+
diff --git a/adr/v4/dashboard.md b/adr/v4/dashboard.md
new file mode 100644
index 000000000..363e5c2e2
--- /dev/null
+++ b/adr/v4/dashboard.md
@@ -0,0 +1,163 @@
+# Management
+
+```
+Users {
+ Existing users[] {
+ Edit
+ Delete
+ }
+ Add new user {
+ Username
+ Email
+ Password
+ OAuth
+ Permissions {
+ Manage settings
+ Manage teams and users
+ Create/delete repositories
+ Create/write content
+ }
+ }
+}
+
+Teams[] {
+ Existing teams[] {
+ Edit
+ Delete
+ }
+ Add new team {
+ Name
+ Permissions {
+ Manage settings
+ Manage teams and users
+ Create/delete repositories
+ Create/write content
+ }
+ }
+}
+
+Repositories[] {
+ Name (Identifier)
+ Redeployments Enabled
+ Type (Genric, Maven, Docker)
+ Owner (user)
+ Enable API
+ Storage provider {
+ Local {
+ Quota
+ Mount
+ }
+ S3 {
+ Authentication {
+ Bucket
+ Region
+ Access Key
+ Secret Key
+ }
+ Custom prefix
+ Method: Restream / Redirect
+ }
+ }
+ ...on Maven {
+ Preserve snapshots
+ Mirrors[] {
+ Link (URL or local id)
+ Store
+ Groups # GAVs that can be requested from this mirror
+ Allowed extensions
+ Timeouts {
+ Connect
+ Read
+ }
+ Authentication {
+ Basic {
+ Username
+ Password
+ }
+ Header {
+ Name
+ Value
+ }
+ }
+ HTTP Proxy {
+ HTTP or Socks
+ }
+ }
+ }
+ ...on Docker {
+ Mirrors {
+ Link (URL or local id)
+ Store
+ Filter
+ Authentication {
+ Basic {
+ Username
+ Password
+ }
+ }
+ HTTP Proxy {
+
+ }
+ }
+ }
+}
+
+Projects {
+ Identifier
+ Owner (user)
+ Display Name
+ Pinned (on front page)
+ Logo (optional)
+ Routes[] {
+ Repository
+ Path
+ }
+}
+
+Settings {
+ Authentication {
+ Local {
+ Allow registration
+ }
+ SSO {
+ Google {
+ Client ID
+ Client Secret
+ // todo: check extra fields
+ }
+ }
+ LDAP {
+ Host
+ Port
+ Base DN
+ Search-User DN
+ Search-User Password
+ Type attribute
+ User attribute
+ User filter
+ User type (persistent, temporary)
+ }
+ }
+
+ UI {
+ Id
+ Title
+ Description
+ Website
+ Logo
+ Search {
+ Enabled
+ }
+ ICP License
+ }
+
+ Statistics {
+ Enabled
+ Accuracy (daily, weekly, monthly, yearly)
+ }
+
+ Other {
+ Forwarded IP (header)
+ }
+}
+```
\ No newline at end of file
diff --git a/adr/v4/database.md b/adr/v4/database.md
new file mode 100644
index 000000000..2e43b351f
--- /dev/null
+++ b/adr/v4/database.md
@@ -0,0 +1,34 @@
+# Database
+
+We want to try out Sqiffy for the database layer, so we can reduce codebase size + have something more stable than Exposed.
+
+### Schema
+
+We'll figure out the schema as we go, but we'll start with the following entities:
+
+```
+ Repository
+
+ ^
+ |
+ |
+ |
+
+Project <---------- Route
+
+ ^
+ |
+ |
+ |
+ v
+
+ RouteAccess <------- Token <-------- User <------> Team
+
+ ^
+ |
+ |
+ |
+
+ Authentication
+
+```
\ No newline at end of file
diff --git a/adr/v4/repositories.md b/adr/v4/repositories.md
new file mode 100644
index 000000000..29557d8f0
--- /dev/null
+++ b/adr/v4/repositories.md
@@ -0,0 +1,19 @@
+# Repositories
+
+### Generic
+
+Can store any kind of file, a little bit like a regular FTP.
+
+### Maven
+
+Pretty much a generic repository, but with filter for Maven-specific files + API.
+
+### Docker
+
+New type of repository, with Docker-specific API.
+
+* https://github.com/reposilite-playground/oci-repository-prototype - for more details
+
+### NPM (not confirmed)
+
+New type of repository, with NPM-specific API.
\ No newline at end of file
diff --git a/adr/v4/ui.md b/adr/v4/ui.md
new file mode 100644
index 000000000..098d009dd
--- /dev/null
+++ b/adr/v4/ui.md
@@ -0,0 +1,27 @@
+# UI
+
+We want to try to build a "simple" UI using JTE (compiled) + HTMX + TailwindCSS + JS (client-side, JSDoc only).
+The color scheme should be +/- the same as the current one.
+
+## Views
+
+### Initial setup
+
+1. Setup database (SQLite: local no credentials, Remote: PostgreSQL/MySQL credentials)
+2. Setup admin account
+3. Finish
+
+### Home page
+
+1. Logo
+2. Search bar
+3. Pinned projects
+4. Repositories
+
+### Login
+
+1. Via credentials / SSO
+
+### Dashboard
+
+See [Dashboard](dashboard.md)
\ No newline at end of file
diff --git a/adr/v4/user-system.md b/adr/v4/user-system.md
new file mode 100644
index 000000000..1893fd98d
--- /dev/null
+++ b/adr/v4/user-system.md
@@ -0,0 +1,81 @@
+# User system
+
+### Context
+
+Reposilite 2.x & 3.x didn't have a concept of users - the whole system was based on tokens.
+Although it was a simple and effective solution,
+it was also limited in terms of user management and permissions for the end-users.
+
+### Proposal
+We will introduce a new user system that will allow users manage their own accounts
+& generate granular tokens with specific permissions.
+
+### Design
+
+The user system will be based on the following entities:
+
+```
+Team - a group of users sharing the same permissions {
+ UserPermissions[] - a set of rules that define what the team can do {
+ - manage settings
+ - manage teams and users
+ - create/delete repositories
+ - create/write content
+ }
+
+ Users[] - a person that can log in to the system {
+ Username
+ Email (optional) - used for password recovery, notifications, etc.
+ Password (optional) - used for password-based authentication
+ Oauth (optional) - used for OAuth-based authentication
+ UserPermissions[] - a set of rules that define what the user can do
+
+ Tokens[] - a unique identifier that can be used to authenticate the user {
+ UserPermissions[] - selected permissions that define what the token can do
+ RouteAccess[] {
+ Project.Route OR custom path
+ ProjectAccessPermissions[] - a set of rules that define what the token can do {
+ - read
+ - write
+ }
+ }
+ }
+ }
+}
+
+Project {
+ Name
+ Routes[] - a set of rules that define what paths the token can access {
+ Repository - repo
+ Path (optional) - e.g. gav for maven repos
+ }
+}
+```
+
+### UX
+
+##### Case 1: From zero to first successful deployment
+
+1. User starts Reposilite
+2. On the first run, the user is asked to create an admin account
+3. User creates an admin account (the admin team is pre-created)
+4. It is suggested to user to create a new access token
+5. User creates a new access token
+5.1. Access token with full permissions is created _(simple way)_
+5.2. User generates token with a specific set of permissions _(recommended)_
+ - Create a project and assign routes
+ - Select following routes in the access token UI
+6. User copies the token and uses it to authenticate with Reposilite
+
+
+##### Case 2: A new user joins the team
+
+1. Manager (user with management permissions) goes to the user management section
+2. Manager creates a new user account with permission
+3. User logs in to the UI, chooses a password, and logs in
+4. User creates a new access token
+ 4.1. Access token with full permissions is created _(simple way)_
+ 4.2. User generates token with a specific set of permissions _(recommended)_
+ - Create a project and assign routes
+ - Select following routes in the access token UI
+5. User can deploy artifacts to the repository using the token
\ No newline at end of file