diff --git a/charts/auth-proxy/values.yaml b/charts/auth-proxy/values.yaml
index df26e50..78fe5e3 100644
--- a/charts/auth-proxy/values.yaml
+++ b/charts/auth-proxy/values.yaml
@@ -6,7 +6,7 @@
 upstream: bar.svc.cluster.local
 whoAmIAddr: https://accounts.example.com/sessions/whoami
 loginAddr: https://accounts-ui.example.com/login
-membershipAddr: https://memberships.p.example.com/api/user
+membershipAddr: https://memberships.p.example.com
 membershipPublicAddr: https://memberships.p.example.com
 groups: ""
 portName: http
diff --git a/core/auth/memberships/main.go b/core/auth/memberships/main.go
index c7df14e..8322933 100644
--- a/core/auth/memberships/main.go
+++ b/core/auth/memberships/main.go
@@ -11,14 +11,13 @@
 	"net/http"
 	"net/url"
 	"regexp"
+	"slices"
 	"strings"
 	"sync"
 
-	"github.com/ncruces/go-sqlite3"
+	"github.com/gorilla/mux"
 	_ "github.com/ncruces/go-sqlite3/driver"
 	_ "github.com/ncruces/go-sqlite3/embed"
-
-	"github.com/gorilla/mux"
 )
 
 var port = flag.Int("port", 8080, "Port to listen on")
@@ -40,37 +39,6 @@
 	h.h.ServeHTTP(w, r)
 }
 
-type Store interface {
-	// Initializes store with admin user and their groups.
-	Init(user, email string, groups []string) error
-	CreateGroup(owner string, group Group) error
-	AddChildGroup(parent, child string) error
-	AddOwnerGroup(owned_group, owner_group string) error
-	DoesGroupExist(group string) (bool, error)
-	GetGroupsOwnedBy(user string) ([]Group, error)
-	GetGroupsUserBelongsTo(user string) ([]Group, error)
-	IsGroupOwner(user, group string) (bool, error)
-	IsMemberOfOwnerGroup(user, group string) (bool, error)
-	AddGroupMember(user, group string) error
-	AddGroupOwner(user, group string) error
-	GetGroupOwners(group string) ([]string, error)
-	GetGroupOwnerGroups(group string) ([]Group, error)
-	GetGroupMembers(group string) ([]string, error)
-	GetGroupDescription(group string) (string, error)
-	GetAllTransitiveGroupsForUser(user string) ([]Group, error)
-	GetGroupsGroupBelongsTo(group string) ([]Group, error)
-	GetDirectChildrenGroups(group string) ([]Group, error)
-	GetAllTransitiveGroupsForGroup(group string) ([]Group, error)
-	RemoveFromGroupToGroup(parent, child string) error
-	RemoveUserFromTable(username, groupName, tableName string) error
-	GetAllGroups() ([]Group, error)
-	GetUsers(username []string) ([]User, error)
-	GetUser(username string) (User, error)
-	AddSSHKeyForUser(username, sshKey string) error
-	RemoveSSHKeyForUser(username, sshKey string) error
-	CreateUser(user, email string) error
-}
-
 type Server struct {
 	store         Store
 	syncAddresses map[string]struct{}
@@ -78,597 +46,24 @@
 }
 
 type Group struct {
-	Name        string
-	Description string
+	Id          string `json:"id"`
+	Title       string `json:"title"`
+	Description string `json:"description"`
 }
 
 type User struct {
-	Username      string   `json:"username"`
-	Email         string   `json:"email"`
-	SSHPublicKeys []string `json:"sshPublicKeys,omitempty"`
-}
-
-type SQLiteStore struct {
-	db *sql.DB
-}
-
-const (
-	ErrorUniqueConstraintViolation     = 2067
-	ErrorConstraintPrimaryKeyViolation = 1555
-)
-
-func NewSQLiteStore(db *sql.DB) (*SQLiteStore, error) {
-	_, err := db.Exec(`
-		CREATE TABLE IF NOT EXISTS groups (
-			name TEXT PRIMARY KEY,
-			description TEXT
-		);
-		CREATE TABLE IF NOT EXISTS owners (
-			username TEXT,
-			group_name TEXT,
-			FOREIGN KEY(group_name) REFERENCES groups(name),
-			UNIQUE (username, group_name)
-		);
-		CREATE TABLE IF NOT EXISTS owner_groups (
-			owner_group TEXT,
-			owned_group TEXT,
-			FOREIGN KEY(owner_group) REFERENCES groups(name),
-			FOREIGN KEY(owned_group) REFERENCES groups(name),
-			UNIQUE (owner_group, owned_group)
-		);
-		CREATE TABLE IF NOT EXISTS group_to_group (
-			parent_group TEXT,
-			child_group TEXT,
-			FOREIGN KEY(parent_group) REFERENCES groups(name),
-			FOREIGN KEY(child_group) REFERENCES groups(name),
-			UNIQUE (parent_group, child_group)
-		);
-		CREATE TABLE IF NOT EXISTS user_to_group (
-			username TEXT,
-			group_name TEXT,
-			FOREIGN KEY(group_name) REFERENCES groups(name),
-			UNIQUE (username, group_name)
-		);
-		CREATE TABLE IF NOT EXISTS users (
-			username TEXT PRIMARY KEY,
-			email TEXT,
-			UNIQUE (email)
-		);
-		CREATE TABLE IF NOT EXISTS user_ssh_keys (
-			username TEXT,
-			ssh_key TEXT,
-			UNIQUE (ssh_key),
-			FOREIGN KEY(username) REFERENCES users(username)
-		);`)
-	if err != nil {
-		return nil, err
-	}
-	return &SQLiteStore{db: db}, nil
-}
-
-func (s *SQLiteStore) Init(user, email string, groups []string) error {
-	tx, err := s.db.Begin()
-	if err != nil {
-		return err
-	}
-	defer tx.Rollback()
-	row := tx.QueryRow("SELECT COUNT(*) FROM groups")
-	var count int
-	if err := row.Scan(&count); err != nil {
-		return err
-	}
-	if count != 0 {
-		return fmt.Errorf("Store already initialised")
-	}
-	query := `INSERT INTO users (username, email) VALUES (?, ?)`
-	if _, err := tx.Exec(query, user, email); err != nil {
-		return err
-	}
-	for _, g := range groups {
-		query = `INSERT INTO groups (name, description) VALUES (?, '')`
-		if _, err := tx.Exec(query, g); err != nil {
-			return err
-		}
-		query = `INSERT INTO owners (username, group_name) VALUES (?, ?)`
-		if _, err := tx.Exec(query, user, g); err != nil {
-			return err
-		}
-		query = `INSERT INTO user_to_group (username, group_name) VALUES (?, ?)`
-		if _, err := tx.Exec(query, user, g); err != nil {
-			return err
-		}
-	}
-	return tx.Commit()
-}
-
-func (s *SQLiteStore) queryGroups(query string, args ...interface{}) ([]Group, error) {
-	groups := make([]Group, 0)
-	rows, err := s.db.Query(query, args...)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	for rows.Next() {
-		var group Group
-		if err := rows.Scan(&group.Name, &group.Description); err != nil {
-			return nil, err
-		}
-		groups = append(groups, group)
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return groups, nil
-}
-
-func (s *SQLiteStore) GetGroupsOwnedBy(user string) ([]Group, error) {
-	query := `
-        SELECT groups.name, groups.description
-        FROM groups
-        JOIN owners ON groups.name = owners.group_name
-        WHERE owners.username = ?`
-	return s.queryGroups(query, user)
-}
-
-func (s *SQLiteStore) GetGroupsUserBelongsTo(user string) ([]Group, error) {
-	query := `
-        SELECT groups.name, groups.description
-        FROM groups
-        JOIN user_to_group ON groups.name = user_to_group.group_name
-        WHERE user_to_group.username = ?`
-	return s.queryGroups(query, user)
-}
-
-func (s *SQLiteStore) CreateGroup(owner string, group Group) error {
-	tx, err := s.db.Begin()
-	if err != nil {
-		return err
-	}
-	defer tx.Rollback()
-	query := `INSERT INTO groups (name, description) VALUES (?, ?)`
-	if _, err := tx.Exec(query, group.Name, group.Description); err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok && sqliteErr.ExtendedCode() == ErrorConstraintPrimaryKeyViolation {
-			return fmt.Errorf("Group with the name %s already exists", group.Name)
-		}
-		return err
-	}
-	query = `INSERT INTO owners (username, group_name) VALUES (?, ?)`
-	if _, err := tx.Exec(query, owner, group.Name); err != nil {
-		return err
-	}
-	return tx.Commit()
-}
-
-func (s *SQLiteStore) IsGroupOwner(user, group string) (bool, error) {
-	query := `
-        SELECT EXISTS (
-            SELECT 1
-            FROM owners
-            WHERE username = ? AND group_name = ?
-        )`
-	var exists bool
-	if err := s.db.QueryRow(query, user, group).Scan(&exists); err != nil {
-		return false, err
-	}
-	return exists, nil
-}
-
-func (s *SQLiteStore) AddGroupMember(user, group string) error {
-	_, err := s.db.Exec(`INSERT INTO user_to_group (username, group_name) VALUES (?, ?)`, user, group)
-	if err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok && sqliteErr.ExtendedCode() == ErrorUniqueConstraintViolation {
-			return fmt.Errorf("%s is already a member of group %s", user, group)
-		}
-		return err
-	}
-	return nil
-}
-
-func (s *SQLiteStore) AddGroupOwner(user, group string) error {
-	_, err := s.db.Exec(`INSERT INTO owners (username, group_name) VALUES (?, ?)`, user, group)
-	if err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok && sqliteErr.ExtendedCode() == ErrorUniqueConstraintViolation {
-			return fmt.Errorf("%s is already an owner of group %s", user, group)
-		}
-		return err
-	}
-	return nil
-}
-
-func (s *SQLiteStore) getUsersByGroup(table, group string) ([]string, error) {
-	query := fmt.Sprintf("SELECT username FROM %s WHERE group_name = ?", table)
-	rows, err := s.db.Query(query, group)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	var users []string
-	for rows.Next() {
-		var username string
-		if err := rows.Scan(&username); err != nil {
-			return nil, err
-		}
-		users = append(users, username)
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return users, nil
-}
-
-func (s *SQLiteStore) GetGroupOwners(group string) ([]string, error) {
-	return s.getUsersByGroup("owners", group)
-}
-
-func (s *SQLiteStore) GetGroupMembers(group string) ([]string, error) {
-	return s.getUsersByGroup("user_to_group", group)
-}
-
-func (s *SQLiteStore) GetGroupDescription(group string) (string, error) {
-	var description string
-	query := `SELECT description FROM groups WHERE name = ?`
-	if err := s.db.QueryRow(query, group).Scan(&description); err != nil {
-		return "", err
-	}
-	return description, nil
-}
-
-func (s *SQLiteStore) DoesGroupExist(group string) (bool, error) {
-	query := `SELECT EXISTS (SELECT 1 FROM groups WHERE name = ?)`
-	var exists bool
-	if err := s.db.QueryRow(query, group).Scan(&exists); err != nil {
-		return false, err
-	}
-	return exists, nil
-}
-
-func (s *SQLiteStore) AddChildGroup(parent, child string) error {
-	if parent == child {
-		return fmt.Errorf("Parent and child groups can not have same name")
-	}
-	exists, err := s.DoesGroupExist(parent)
-	if err != nil {
-		return fmt.Errorf("Error checking parent group existence: %v", err)
-	}
-	if !exists {
-		return fmt.Errorf("Parent group with name %s does not exist", parent)
-	}
-	exists, err = s.DoesGroupExist(child)
-	if err != nil {
-		return fmt.Errorf("Error checking child group existence: %v", err)
-	}
-	if !exists {
-		return fmt.Errorf("Child group with name %s does not exist", child)
-	}
-	parentGroups, err := s.GetAllTransitiveGroupsForGroup(parent)
-	if err != nil {
-		return err
-	}
-	for _, group := range parentGroups {
-		if group.Name == child {
-			return fmt.Errorf("Circular reference detected: group %s is already a parent of group %s", child, parent)
-		}
-	}
-	_, err = s.db.Exec(`INSERT INTO group_to_group (parent_group, child_group) VALUES (?, ?)`, parent, child)
-	if err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok && sqliteErr.ExtendedCode() == ErrorUniqueConstraintViolation {
-			return fmt.Errorf("Child group name %s already exists in group %s", child, parent)
-		}
-		return err
-	}
-	return nil
-}
-
-func (s *SQLiteStore) GetAllTransitiveGroupsForUser(user string) ([]Group, error) {
-	if groups, err := s.GetGroupsUserBelongsTo(user); err != nil {
-		return nil, err
-	} else {
-		visited := map[string]struct{}{}
-		return s.getAllParentGroupsRecursive(groups, visited)
-	}
-}
-
-func (s *SQLiteStore) GetAllTransitiveGroupsForGroup(group string) ([]Group, error) {
-	if p, err := s.GetGroupsGroupBelongsTo(group); err != nil {
-		return nil, err
-	} else {
-		// Mark initial group as visited
-		visited := map[string]struct{}{
-			group: struct{}{},
-		}
-		return s.getAllParentGroupsRecursive(p, visited)
-	}
-}
-
-func (s *SQLiteStore) getAllParentGroupsRecursive(groups []Group, visited map[string]struct{}) ([]Group, error) {
-	var ret []Group
-	for _, g := range groups {
-		if _, ok := visited[g.Name]; ok {
-			continue
-		}
-		visited[g.Name] = struct{}{}
-		ret = append(ret, g)
-		if p, err := s.GetGroupsGroupBelongsTo(g.Name); err != nil {
-			return nil, err
-		} else if res, err := s.getAllParentGroupsRecursive(p, visited); err != nil {
-			return nil, err
-		} else {
-			ret = append(ret, res...)
-		}
-	}
-	return ret, nil
-}
-
-func (s *SQLiteStore) GetGroupsGroupBelongsTo(group string) ([]Group, error) {
-	query := `
-        SELECT groups.name, groups.description
-        FROM groups
-        JOIN group_to_group ON groups.name = group_to_group.parent_group
-        WHERE group_to_group.child_group = ?`
-	rows, err := s.db.Query(query, group)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	var parentGroups []Group
-	for rows.Next() {
-		var parentGroup Group
-		if err := rows.Scan(&parentGroup.Name, &parentGroup.Description); err != nil {
-			return nil, err
-		}
-		parentGroups = append(parentGroups, parentGroup)
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return parentGroups, nil
-}
-
-func (s *SQLiteStore) GetDirectChildrenGroups(group string) ([]Group, error) {
-	query := `
-        SELECT groups.name, groups.description
-        FROM groups
-        JOIN group_to_group ON groups.name = group_to_group.child_group
-        WHERE group_to_group.parent_group = ?`
-	rows, err := s.db.Query(query, group)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	var childrenGroups []Group
-	for rows.Next() {
-		var childGroup Group
-		if err := rows.Scan(&childGroup.Name, &childGroup.Description); err != nil {
-			return nil, err
-		}
-		childrenGroups = append(childrenGroups, childGroup)
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return childrenGroups, nil
-}
-
-func (s *SQLiteStore) RemoveFromGroupToGroup(parent, child string) error {
-	query := `DELETE FROM group_to_group WHERE parent_group = ? AND child_group = ?`
-	rowDeleted, err := s.db.Exec(query, parent, child)
-	if err != nil {
-		return err
-	}
-	rowDeletedNumber, err := rowDeleted.RowsAffected()
-	if err != nil {
-		return err
-	}
-	if rowDeletedNumber == 0 {
-		return fmt.Errorf("Pair of parent '%s' and child '%s' groups not found", parent, child)
-	}
-	return nil
-}
-
-func (s *SQLiteStore) RemoveUserFromTable(username, groupName, tableName string) error {
-	if tableName == "owners" {
-		owners, err := s.GetGroupOwners(groupName)
-		if err != nil {
-			return err
-		}
-		if len(owners) == 1 {
-			return fmt.Errorf("Cannot remove the last owner of the group")
-		}
-	}
-	query := fmt.Sprintf("DELETE FROM %s WHERE username = ? AND group_name = ?", tableName)
-	rowDeleted, err := s.db.Exec(query, username, groupName)
-	if err != nil {
-		return err
-	}
-	rowDeletedNumber, err := rowDeleted.RowsAffected()
-	if err != nil {
-		return err
-	}
-	if rowDeletedNumber == 0 {
-		return fmt.Errorf("Pair of group '%s' and user '%s' not found", groupName, username)
-	}
-	return nil
-}
-
-func (s *SQLiteStore) AddOwnerGroup(owner_group, owned_group string) error {
-	if owned_group == owner_group {
-		return fmt.Errorf("Group can not own itself")
-	}
-	exists, err := s.DoesGroupExist(owned_group)
-	if err != nil {
-		return fmt.Errorf("Error checking owned group existence: %v", err)
-	}
-	if !exists {
-		return fmt.Errorf("Owned group with name %s does not exist", owned_group)
-	}
-	exists, err = s.DoesGroupExist(owner_group)
-	if err != nil {
-		return fmt.Errorf("Error checking owner group existence: %v", err)
-	}
-	if !exists {
-		return fmt.Errorf("Owner group with name %s does not exist", owner_group)
-	}
-	_, err = s.db.Exec(`INSERT INTO owner_groups (owner_group, owned_group) VALUES (?, ?)`, owner_group, owned_group)
-	if err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok && sqliteErr.ExtendedCode() == ErrorUniqueConstraintViolation {
-			return fmt.Errorf("Group named %s is already owner of a group %s", owner_group, owned_group)
-		}
-		return err
-	}
-	return nil
-}
-
-func (s *SQLiteStore) GetGroupOwnerGroups(group string) ([]Group, error) {
-	query := `
-        SELECT groups.name, groups.description
-        FROM groups
-        JOIN owner_groups ON groups.name = owner_groups.owner_group
-        WHERE owner_groups.owned_group = ?`
-	return s.queryGroups(query, group)
-}
-
-func (s *SQLiteStore) IsMemberOfOwnerGroup(user, group string) (bool, error) {
-	query := `
-		SELECT EXISTS (
-			SELECT 1 FROM owner_groups
-			INNER JOIN user_to_group ON owner_groups.owner_group = user_to_group.group_name
-			WHERE owner_groups.owned_group = ? AND user_to_group.username = ?)`
-	var exists bool
-	err := s.db.QueryRow(query, group, user).Scan(&exists)
-	if err != nil {
-		return false, err
-	}
-	return exists, nil
-}
-
-func (s *SQLiteStore) GetAllGroups() ([]Group, error) {
-	query := `SELECT name, description FROM groups`
-	return s.queryGroups(query)
-}
-
-func (s *SQLiteStore) AddSSHKeyForUser(username, sshKey string) error {
-	_, err := s.db.Exec(`INSERT INTO user_ssh_keys (username, ssh_key) VALUES (?, ?)`, username, sshKey)
-	if err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok && sqliteErr.ExtendedCode() == ErrorUniqueConstraintViolation {
-			return fmt.Errorf("%s such SSH public key already exists", sshKey)
-		}
-		return err
-	}
-	return nil
-}
-
-func (s *SQLiteStore) RemoveSSHKeyForUser(username, sshKey string) error {
-	_, err := s.db.Exec(`DELETE FROM user_ssh_keys WHERE username = ? AND ssh_key = ?`, username, sshKey)
-	if err != nil {
-		return err
-	}
-	return nil
-}
-
-func (s *SQLiteStore) GetUsers(usernames []string) ([]User, error) {
-	var rows *sql.Rows
-	var err error
-	query := `
-		SELECT users.username, users.email, GROUP_CONCAT(user_ssh_keys.ssh_key, ',')
-		FROM users
-		LEFT JOIN user_ssh_keys ON users.username = user_ssh_keys.username`
-	var args []interface{}
-	if usernames != nil {
-		if len(usernames) == 0 {
-			return []User{}, nil
-		}
-		query += " WHERE users.username IN ("
-		placeholders := strings.Repeat("?,", len(usernames)-1) + "?"
-		query += placeholders + ") "
-		for _, username := range usernames {
-			args = append(args, username)
-		}
-	}
-	query += " GROUP BY users.username"
-	rows, err = s.db.Query(query, args...)
-	if err != nil {
-		return nil, err
-	}
-	defer rows.Close()
-	var userInfos []User
-	for rows.Next() {
-		var username, email string
-		var sshKeys sql.NullString
-		if err := rows.Scan(&username, &email, &sshKeys); err != nil {
-			return nil, err
-		}
-		user := User{
-			Username: username,
-			Email:    email,
-		}
-		if sshKeys.Valid {
-			user.SSHPublicKeys = strings.Split(sshKeys.String, ",")
-		}
-		userInfos = append(userInfos, user)
-	}
-	if err := rows.Err(); err != nil {
-		return nil, err
-	}
-	return userInfos, nil
-}
-
-func (s *SQLiteStore) GetUser(username string) (User, error) {
-	var user User
-	user.Username = username
-	query := `
-		SELECT users.email, GROUP_CONCAT(user_ssh_keys.ssh_key, ',')
-		FROM users
-		LEFT JOIN user_ssh_keys ON users.username = user_ssh_keys.username
-		WHERE users.username = ?
-		GROUP BY users.username
-	`
-	row := s.db.QueryRow(query, username)
-	var sshKeys sql.NullString
-	err := row.Scan(&user.Email, &sshKeys)
-	if err != nil {
-		if err == sql.ErrNoRows {
-			return User{}, fmt.Errorf("no user found with username %s", username)
-		}
-		return User{}, err
-	}
-	if sshKeys.Valid {
-		user.SSHPublicKeys = strings.Split(sshKeys.String, ",")
-	}
-	return user, nil
-}
-
-func (s *SQLiteStore) CreateUser(user, email string) error {
-	_, err := s.db.Exec(`INSERT INTO users (username, email) VALUES (?, ?)`, user, email)
-	if err != nil {
-		sqliteErr, ok := err.(*sqlite3.Error)
-		if ok {
-			if sqliteErr.ExtendedCode() == ErrorUniqueConstraintViolation {
-				if strings.Contains(err.Error(), "UNIQUE constraint failed: users.username") {
-					return fmt.Errorf("username %s already exists", user)
-				}
-				if strings.Contains(err.Error(), "UNIQUE constraint failed: users.email") {
-					return fmt.Errorf("email %s already exists", email)
-				}
-			}
-		}
-		return err
-	}
-	return nil
+	Id       string `json:"id"`
+	Username string `json:"username"`
+	Email    string `json:"email"`
 }
 
 func getLoggedInUser(r *http.Request) (string, error) {
-	if user := r.Header.Get("X-Forwarded-User"); user != "" {
+	if user := r.Header.Get("X-Forwarded-UserId"); user != "" {
 		return user, nil
 	} else {
 		return "", fmt.Errorf("unauthenticated")
 	}
-	// return "tabo", nil
+	// return "0063f4b6-29cb-4bd6-b8ce-1f6b203d490f", nil
 }
 
 type Status int
@@ -683,13 +78,13 @@
 	go func() {
 		r := mux.NewRouter()
 		r.PathPrefix("/static/").Handler(cachingHandler{http.FileServer(http.FS(staticResources))})
-		r.HandleFunc("/group/{group-name}/add-user/", s.addUserToGroupHandler).Methods(http.MethodPost)
-		r.HandleFunc("/group/{parent-group}/add-child-group", s.addChildGroupHandler).Methods(http.MethodPost)
-		r.HandleFunc("/group/{owned-group}/add-owner-group", s.addOwnerGroupHandler).Methods(http.MethodPost)
-		r.HandleFunc("/group/{parent-group}/remove-child-group/{child-group}", s.removeChildGroupHandler).Methods(http.MethodPost)
-		r.HandleFunc("/group/{group-name}/remove-owner/{username}", s.removeOwnerFromGroupHandler).Methods(http.MethodPost)
-		r.HandleFunc("/group/{group-name}/remove-member/{username}", s.removeMemberFromGroupHandler).Methods(http.MethodPost)
-		r.HandleFunc("/group/{group-name}", s.groupHandler)
+		r.HandleFunc("/group/{groupId:.*}/add-user/", s.addUserToGroupHandler).Methods(http.MethodPost)
+		r.HandleFunc("/group/{groupId:.*}/add-child-group", s.addChildGroupHandler).Methods(http.MethodPost)
+		r.HandleFunc("/group/{groupId:.*}/add-owner-group", s.addOwnerGroupHandler).Methods(http.MethodPost)
+		r.HandleFunc("/group/{groupId:.*}/remove-child-group/{otherId:.*}", s.removeChildGroupHandler).Methods(http.MethodPost)
+		r.HandleFunc("/group/{groupId:.*}/remove-owner/{username}", s.removeOwnerFromGroupHandler).Methods(http.MethodPost)
+		r.HandleFunc("/group/{groupId:.*}/remove-member/{username}", s.removeMemberFromGroupHandler).Methods(http.MethodPost)
+		r.HandleFunc("/group/{groupId:.*}", s.groupHandler)
 		r.HandleFunc("/user/{username}/ssh-key", s.addSSHKeyForUserHandler).Methods(http.MethodPost)
 		r.HandleFunc("/user/{username}/remove-ssh-key", s.removeSSHKeyForUserHandler).Methods(http.MethodPost)
 		r.HandleFunc("/user/{username}", s.userHandler)
@@ -705,6 +100,12 @@
 		r.HandleFunc("/api/user/{username}", s.apiMemberOfHandler)
 		r.HandleFunc("/api/users", s.apiGetAllUsers).Methods(http.MethodGet)
 		r.HandleFunc("/api/users", s.apiCreateUser).Methods(http.MethodPost)
+		r.HandleFunc("/api/group", s.apiCreateGroup).Methods(http.MethodPost)
+		r.HandleFunc("/api/add-group-user", s.apiAddUserToGroup).Methods(http.MethodPost)
+		r.HandleFunc("/api/remove-group-user", s.apiRemoveUserFromGroup).Methods(http.MethodPost)
+		r.HandleFunc("/api/add-group-group", s.apiAddGroupToGroup).Methods(http.MethodPost)
+		r.HandleFunc("/api/remove-group-group", s.apiRemoveGroupFromGroup).Methods(http.MethodPost)
+		r.HandleFunc("/api/get-group", s.apiGetGroup).Methods(http.MethodPost)
 		e <- http.ListenAndServe(fmt.Sprintf(":%d", *apiPort), r)
 	}()
 	return <-e
@@ -715,23 +116,30 @@
 	Membership string
 }
 
-func (s *Server) checkIsOwner(w http.ResponseWriter, user, group string) error {
-	isOwner, err := s.store.IsGroupOwner(user, group)
+func (s *Server) checkIsOwner(w http.ResponseWriter, userId, groupId string) error {
+	ownerUsers, err := s.store.GetOwnerUsers(nil, groupId)
 	if err != nil {
 		return err
 	}
-	if isOwner {
+	if slices.ContainsFunc(ownerUsers, func(u User) bool {
+		return u.Id == userId
+	}) {
 		return nil
 	}
-	// TODO(dtabidze): right now this only checks if user is member of just one lvl upper group. should add transitive group check.
-	isMemberOfOwnerGroup, err := s.store.IsMemberOfOwnerGroup(user, group)
+	ownerIds, err := s.store.GetOwnerGroups(nil, groupId)
 	if err != nil {
 		return err
 	}
-	if !isMemberOfOwnerGroup {
-		return fmt.Errorf("You are not the owner or a member of any owner group of the group %s", group)
+	canActAs, err := s.store.GetGroupsUserCanActAs(nil, userId)
+	if err != nil {
+		return err
 	}
-	return nil
+	for _, g := range canActAs {
+		if slices.Index(ownerIds, g) != -1 {
+			return nil
+		}
+	}
+	return fmt.Errorf("not an owner")
 }
 
 type templates struct {
@@ -772,13 +180,12 @@
 }
 
 type UserPageData struct {
+	User             User
 	OwnerGroups      []Group
 	MembershipGroups []Group
 	TransitiveGroups []Group
 	LoggedInUserPage bool
-	CurrentUser      string
 	SSHPublicKeys    []string
-	Email            string
 	ErrorMessage     string
 }
 
@@ -793,34 +200,38 @@
 	user := strings.ToLower(vars["username"])
 	// TODO(dtabidze): should check if username exists or not.
 	loggedInUserPage := loggedInUser == user
-	ownerGroups, err := s.store.GetGroupsOwnedBy(user)
+	ownerGroups, err := s.store.GetGroupsUserOwns(nil, user)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	membershipGroups, err := s.store.GetGroupsUserBelongsTo(user)
+	membershipGroups, err := s.store.GetGroupsUserIsMemberOf(nil, user)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	transitiveGroups, err := s.store.GetAllTransitiveGroupsForUser(user)
+	transitiveGroups, err := s.store.GetGroupsUserCanActAs(nil, user)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	userInfo, err := s.store.GetUser(user)
+	userInfo, err := s.store.GetUser(nil, user)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	sshPublicKeys, err := s.store.GetUserPublicKeys(nil, user)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
 	data := UserPageData{
+		User:             userInfo,
 		OwnerGroups:      ownerGroups,
 		MembershipGroups: membershipGroups,
 		TransitiveGroups: transitiveGroups,
 		LoggedInUserPage: loggedInUserPage,
-		CurrentUser:      user,
-		SSHPublicKeys:    userInfo.SSHPublicKeys,
-		Email:            userInfo.Email,
+		SSHPublicKeys:    sshPublicKeys,
 		ErrorMessage:     errorMsg,
 	}
 	templates, err := parseTemplates(tmpls)
@@ -845,15 +256,16 @@
 		return
 	}
 	var group Group
-	group.Name = r.PostFormValue("group-name")
-	if err := isValidGroupName(group.Name); err != nil {
+	group.Id = r.PostFormValue("id")
+	group.Title = r.PostFormValue("title")
+	group.Description = r.PostFormValue("description")
+	if err := isValidGroupId(group.Id); err != nil {
 		// http.Error(w, err.Error(), http.StatusBadRequest)
 		redirectURL := fmt.Sprintf("/user/%s?errorMessage=%s", loggedInUser, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	group.Description = r.PostFormValue("description")
-	if err := s.store.CreateGroup(loggedInUser, group); err != nil {
+	if err := s.store.CreateGroup(nil, loggedInUser, group); err != nil {
 		// http.Error(w, err.Error(), http.StatusInternalServerError)
 		redirectURL := fmt.Sprintf("/user/%s?errorMessage=%s", loggedInUser, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
@@ -863,11 +275,13 @@
 }
 
 type GroupPageData struct {
-	GroupName        string
+	GroupId          string
+	Title            string
 	Description      string
-	Owners           []string
-	Members          []string
+	Owners           []User
+	Members          []User
 	AllGroups        []Group
+	AllUsers         []User
 	TransitiveGroups []Group
 	ChildGroups      []Group
 	OwnerGroups      []Group
@@ -882,62 +296,59 @@
 	}
 	errorMsg := r.URL.Query().Get("errorMessage")
 	vars := mux.Vars(r)
-	groupName := vars["group-name"]
-	exists, err := s.store.DoesGroupExist(groupName)
+	groupId := normalizeGroupId(vars["groupId"])
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	if !exists {
-		errorMsg = fmt.Sprintf("group with the name '%s' not found", groupName)
-		http.Error(w, errorMsg, http.StatusNotFound)
-		return
-	}
+	g, err := s.store.GetGroup(nil, groupId)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	owners, err := s.store.GetGroupOwners(groupName)
+	owners, err := s.store.GetOwnerUsers(nil, groupId)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	members, err := s.store.GetGroupMembers(groupName)
+	members, err := s.store.GetMemberUsers(nil, groupId)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	description, err := s.store.GetGroupDescription(groupName)
+	allUsers, err := s.store.GetAllUsers(nil)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	allGroups, err := s.store.GetAllGroups()
+	allGroups, err := s.store.GetAllGroups(nil)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	transitiveGroups, err := s.store.GetAllTransitiveGroupsForGroup(groupName)
+	transitiveGroups, err := s.store.GetGroupsGroupCanActAs(nil, groupId)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	childGroups, err := s.store.GetDirectChildrenGroups(groupName)
+	childGroups, err := s.store.GetMemberGroups(nil, groupId)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	ownerGroups, err := s.store.GetGroupOwnerGroups(groupName)
+	ownerGroups, err := s.store.GetOwnerGroups(nil, groupId)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
 	data := GroupPageData{
-		GroupName:        groupName,
-		Description:      description,
+		GroupId:          groupId,
+		Title:            g.Title,
+		Description:      g.Description,
 		Owners:           owners,
 		Members:          members,
 		AllGroups:        allGroups,
+		AllUsers:         allUsers,
 		TransitiveGroups: transitiveGroups,
 		ChildGroups:      childGroups,
 		OwnerGroups:      ownerGroups,
@@ -961,28 +372,28 @@
 		return
 	}
 	vars := mux.Vars(r)
-	parentGroup := vars["parent-group"]
-	childGroup := vars["child-group"]
-	if err := isValidGroupName(parentGroup); err != nil {
+	groupId := normalizeGroupId(vars["groupId"])
+	otherId := vars["otherId"]
+	if err := isValidGroupId(groupId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := isValidGroupName(childGroup); err != nil {
+	if err := isValidGroupId(otherId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.checkIsOwner(w, loggedInUser, parentGroup); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", parentGroup, url.QueryEscape(err.Error()))
+	if err := s.checkIsOwner(w, loggedInUser, groupId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusSeeOther)
 		return
 	}
-	err = s.store.RemoveFromGroupToGroup(parentGroup, childGroup)
+	err = s.store.RemoveMemberGroup(nil, groupId, otherId)
 	if err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", parentGroup, url.QueryEscape(err.Error()))
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	http.Redirect(w, r, "/group/"+parentGroup, http.StatusSeeOther)
+	http.Redirect(w, r, "/group/"+groupId, http.StatusSeeOther)
 }
 
 func (s *Server) removeOwnerFromGroupHandler(w http.ResponseWriter, r *http.Request) {
@@ -993,24 +404,23 @@
 	}
 	vars := mux.Vars(r)
 	username := vars["username"]
-	groupName := vars["group-name"]
-	tableName := "owners"
-	if err := isValidGroupName(groupName); err != nil {
+	groupId := normalizeGroupId(vars["groupId"])
+	if err := isValidGroupId(groupId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.checkIsOwner(w, loggedInUser, groupName); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupName, url.QueryEscape(err.Error()))
+	if err := s.checkIsOwner(w, loggedInUser, groupId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusSeeOther)
 		return
 	}
-	err = s.store.RemoveUserFromTable(username, groupName, tableName)
+	err = s.store.RemoveOwnerUser(nil, groupId, username)
 	if err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupName, url.QueryEscape(err.Error()))
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	http.Redirect(w, r, "/group/"+groupName, http.StatusSeeOther)
+	http.Redirect(w, r, "/group/"+groupId, http.StatusSeeOther)
 }
 
 func (s *Server) removeMemberFromGroupHandler(w http.ResponseWriter, r *http.Request) {
@@ -1021,24 +431,23 @@
 	}
 	vars := mux.Vars(r)
 	username := vars["username"]
-	groupName := vars["group-name"]
-	tableName := "user_to_group"
-	if err := isValidGroupName(groupName); err != nil {
+	groupId := normalizeGroupId(vars["groupId"])
+	if err := isValidGroupId(groupId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.checkIsOwner(w, loggedInUser, groupName); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupName, url.QueryEscape(err.Error()))
+	if err := s.checkIsOwner(w, loggedInUser, groupId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusSeeOther)
 		return
 	}
-	err = s.store.RemoveUserFromTable(username, groupName, tableName)
+	err = s.store.RemoveMemberUser(nil, groupId, username)
 	if err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupName, url.QueryEscape(err.Error()))
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	http.Redirect(w, r, "/group/"+groupName, http.StatusSeeOther)
+	http.Redirect(w, r, "/group/"+groupId, http.StatusSeeOther)
 }
 
 func (s *Server) addUserToGroupHandler(w http.ResponseWriter, r *http.Request) {
@@ -1048,13 +457,13 @@
 		return
 	}
 	vars := mux.Vars(r)
-	groupName := vars["group-name"]
-	if err := isValidGroupName(groupName); err != nil {
+	groupId := normalizeGroupId(vars["groupId"])
+	if err := isValidGroupId(groupId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	username := strings.ToLower(r.FormValue("username"))
-	if username == "" {
+	userId := strings.ToLower(r.FormValue("userId"))
+	if userId == "" {
 		http.Error(w, "Username parameter is required", http.StatusBadRequest)
 		return
 	}
@@ -1063,26 +472,26 @@
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.checkIsOwner(w, loggedInUser, groupName); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupName, url.QueryEscape(err.Error()))
+	if err := s.checkIsOwner(w, loggedInUser, groupId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusSeeOther)
 		return
 	}
 	switch status {
 	case Owner:
-		err = s.store.AddGroupOwner(username, groupName)
+		err = s.store.AddOwnerUser(nil, groupId, userId)
 	case Member:
-		err = s.store.AddGroupMember(username, groupName)
+		err = s.store.AddMemberUser(nil, groupId, userId)
 	default:
 		http.Error(w, "Invalid status", http.StatusBadRequest)
 		return
 	}
 	if err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupName, url.QueryEscape(err.Error()))
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	http.Redirect(w, r, "/group/"+groupName, http.StatusSeeOther)
+	http.Redirect(w, r, "/group/"+groupId, http.StatusSeeOther)
 }
 
 func (s *Server) addChildGroupHandler(w http.ResponseWriter, r *http.Request) {
@@ -1093,27 +502,27 @@
 		return
 	}
 	vars := mux.Vars(r)
-	parentGroup := vars["parent-group"]
-	if err := isValidGroupName(parentGroup); err != nil {
+	groupId := normalizeGroupId(vars["groupId"])
+	otherId := r.FormValue("otherId")
+	if err := isValidGroupId(groupId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	childGroup := r.FormValue("child-group")
-	if err := isValidGroupName(childGroup); err != nil {
+	if err := isValidGroupId(otherId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.checkIsOwner(w, loggedInUser, parentGroup); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", parentGroup, url.QueryEscape(err.Error()))
+	if err := s.checkIsOwner(w, loggedInUser, groupId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusSeeOther)
 		return
 	}
-	if err := s.store.AddChildGroup(parentGroup, childGroup); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", parentGroup, url.QueryEscape(err.Error()))
+	if err := s.store.AddMemberGroup(nil, groupId, otherId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	http.Redirect(w, r, "/group/"+parentGroup, http.StatusSeeOther)
+	http.Redirect(w, r, "/group/"+groupId, http.StatusSeeOther)
 }
 
 func (s *Server) addOwnerGroupHandler(w http.ResponseWriter, r *http.Request) {
@@ -1123,27 +532,27 @@
 		return
 	}
 	vars := mux.Vars(r)
-	ownedGroup := vars["owned-group"]
-	if err := isValidGroupName(ownedGroup); err != nil {
+	groupId := normalizeGroupId(vars["groupId"])
+	otherId := r.FormValue("otherId")
+	if err := isValidGroupId(groupId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	ownerGroup := r.FormValue("owner-group")
-	if err := isValidGroupName(ownerGroup); err != nil {
+	if err := isValidGroupId(otherId); err != nil {
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.checkIsOwner(w, loggedInUser, ownedGroup); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", ownedGroup, url.QueryEscape(err.Error()))
+	if err := s.checkIsOwner(w, loggedInUser, groupId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusSeeOther)
 		return
 	}
-	if err := s.store.AddOwnerGroup(ownerGroup, ownedGroup); err != nil {
-		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", ownedGroup, url.QueryEscape(err.Error()))
+	if err := s.store.AddOwnerGroup(nil, groupId, otherId); err != nil {
+		redirectURL := fmt.Sprintf("/group/%s?errorMessage=%s", groupId, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
 	}
-	http.Redirect(w, r, "/group/"+ownedGroup, http.StatusSeeOther)
+	http.Redirect(w, r, "/group/"+groupId, http.StatusSeeOther)
 }
 
 func (s *Server) addSSHKeyForUserHandler(w http.ResponseWriter, r *http.Request) {
@@ -1164,7 +573,7 @@
 		http.Error(w, "SSH key not present", http.StatusBadRequest)
 		return
 	}
-	if err := s.store.AddSSHKeyForUser(strings.ToLower(username), sshKey); err != nil {
+	if err := s.store.AddUserPublicKey(nil, strings.ToLower(username), sshKey); err != nil {
 		redirectURL := fmt.Sprintf("/user/%s?errorMessage=%s", loggedInUser, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
@@ -1194,7 +603,7 @@
 		http.Error(w, "SSH key not present", http.StatusBadRequest)
 		return
 	}
-	if err := s.store.RemoveSSHKeyForUser(username, sshKey); err != nil {
+	if err := s.store.RemoveUserPublicKey(nil, username, sshKey); err != nil {
 		redirectURL := fmt.Sprintf("/user/%s?errorMessage=%s", loggedInUser, url.QueryEscape(err.Error()))
 		http.Redirect(w, r, redirectURL, http.StatusFound)
 		return
@@ -1203,9 +612,8 @@
 }
 
 type initRequest struct {
-	User   string   `json:"user"`
-	Email  string   `json:"email"`
-	Groups []string `json:"groups"`
+	User   User    `json:"user"`
+	Groups []Group `json:"groups"`
 }
 
 func (s *Server) apiInitHandler(w http.ResponseWriter, r *http.Request) {
@@ -1214,14 +622,15 @@
 		http.Error(w, err.Error(), http.StatusBadRequest)
 		return
 	}
-	if err := s.store.Init(req.User, req.Email, req.Groups); err != nil {
+	if err := s.store.Init(req.User, req.Groups); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
 }
 
 type userInfo struct {
-	MemberOf []string `json:"memberOf"`
+	CanActAs []Group `json:"canActAs"`
+	OwnerOf  []Group `json:"ownerOf"`
 }
 
 func (s *Server) apiMemberOfHandler(w http.ResponseWriter, r *http.Request) {
@@ -1232,17 +641,14 @@
 		return
 	}
 	user = strings.ToLower(user)
-	transitiveGroups, err := s.store.GetAllTransitiveGroupsForUser(user)
+	transitiveGroups, err := s.store.GetGroupsUserCanActAs(nil, user)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
-	var groupNames []string
-	for _, group := range transitiveGroups {
-		groupNames = append(groupNames, group.Name)
-	}
+	owned, err := s.store.GetGroupsUserOwns(nil, user)
 	w.Header().Set("Content-Type", "application/json")
-	if err := json.NewEncoder(w).Encode(userInfo{groupNames}); err != nil {
+	if err := json.NewEncoder(w).Encode(userInfo{transitiveGroups, owned}); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
@@ -1254,37 +660,37 @@
 	var err error
 	groups := r.FormValue("groups")
 	if groups == "" {
-		users, err = s.store.GetUsers(nil)
+		users, err = s.store.GetAllUsers(nil)
 	} else {
 		uniqueUsers := make(map[string]struct{})
 		g := strings.Split(groups, ",")
 		uniqueTG := make(map[string]struct{})
 		for _, group := range g {
 			uniqueTG[group] = struct{}{}
-			trGroups, err := s.store.GetAllTransitiveGroupsForGroup(group)
+			trGroups, err := s.store.GetGroupsGroupCanActAs(nil, group)
 			if err != nil {
 				http.Error(w, err.Error(), http.StatusInternalServerError)
 				return
 			}
 			for _, tg := range trGroups {
-				uniqueTG[tg.Name] = struct{}{}
+				uniqueTG[tg.Title] = struct{}{}
 			}
 		}
 		for group := range uniqueTG {
-			u, err := s.store.GetGroupMembers(group)
+			u, err := s.store.GetMemberUsers(nil, group)
 			if err != nil {
 				http.Error(w, err.Error(), http.StatusInternalServerError)
 				return
 			}
 			for _, user := range u {
-				uniqueUsers[user] = struct{}{}
+				uniqueUsers[user.Username] = struct{}{}
 			}
 		}
 		usernames := make([]string, 0, len(uniqueUsers))
 		for username := range uniqueUsers {
 			usernames = append(usernames, username)
 		}
-		users, err = s.store.GetUsers(usernames)
+		users, err = s.store.GetUsers(nil, usernames)
 	}
 	if err != nil {
 		http.Error(w, "Failed to retrieve user infos", http.StatusInternalServerError)
@@ -1297,19 +703,18 @@
 	}
 }
 
-type createUserRequest struct {
-	User  string `json:"user"`
-	Email string `json:"email"`
-}
-
 func (s *Server) apiCreateUser(w http.ResponseWriter, r *http.Request) {
 	defer s.pingAllSyncAddresses()
-	var req createUserRequest
+	var req User
 	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
 		http.Error(w, "Invalid request body", http.StatusBadRequest)
 		return
 	}
-	if req.User == "" {
+	if req.Id == "" {
+		http.Error(w, "Id cannot be empty", http.StatusBadRequest)
+		return
+	}
+	if req.Username == "" {
 		http.Error(w, "Username cannot be empty", http.StatusBadRequest)
 		return
 	}
@@ -1317,7 +722,211 @@
 		http.Error(w, "Email cannot be empty", http.StatusBadRequest)
 		return
 	}
-	if err := s.store.CreateUser(strings.ToLower(req.User), strings.ToLower(req.Email)); err != nil {
+	user := User{Id: req.Id, Username: strings.ToLower(req.Username), Email: strings.ToLower(req.Email)}
+	if err := s.store.CreateUser(nil, user); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+type createGroupRequest struct {
+	UserId      string `json:"userId"`
+	GroupId     string `json:"groupId"`
+	Title       string `json:"title"`
+	Description string `json:"description"`
+}
+
+func (s *Server) apiCreateGroup(w http.ResponseWriter, r *http.Request) {
+	var req createGroupRequest
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, "Invalid request body", http.StatusBadRequest)
+		return
+	}
+	if err := s.store.CreateGroup(nil, req.UserId, Group{req.GroupId, req.Title, req.Description}); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+type apiGetGroupReq struct {
+	GroupId string `json:"groupId"`
+}
+
+// TODO(gio): update client
+type apiGetGroupResp struct {
+	Self         Group   `json:"self"`
+	Members      []User  `json:"members"`
+	Owners       []User  `json:"owners"`
+	MemberGroups []Group `json:"memberGroups"`
+	OwnerGroups  []Group `json:"ownerGroups"`
+}
+
+func (s *Server) apiGetGroup(w http.ResponseWriter, r *http.Request) {
+	var req apiGetGroupReq
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, "missing group name", http.StatusBadRequest)
+		return
+	}
+	group, err := s.store.GetGroup(nil, req.GroupId)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	members, err := s.store.GetMemberUsers(nil, req.GroupId)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	owners, err := s.store.GetOwnerUsers(nil, req.GroupId)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	memberGroups, err := s.store.GetMemberGroups(nil, req.GroupId)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	ownerGroups, err := s.store.GetOwnerGroups(nil, req.GroupId)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	if err := json.NewEncoder(w).Encode(apiGetGroupResp{group, members, owners, memberGroups, ownerGroups}); err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+type userGroupStatus struct {
+	GroupId string `json:"groupId"`
+	UserId  string `json:"userId"`
+	Status  string `json:"status"`
+}
+
+func (s *Server) apiAddUserToGroup(w http.ResponseWriter, r *http.Request) {
+	var req userGroupStatus
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, "Invalid request body", http.StatusBadRequest)
+		return
+	}
+	status, err := convertStatus(req.Status)
+	if err != nil {
+		http.Error(w, "Invalid status", http.StatusBadRequest)
+		return
+	}
+	fmt.Printf("AAA %+v\n", req)
+	switch status {
+	case Member:
+		err = s.store.AddMemberUser(nil, req.GroupId, req.UserId)
+	case Owner:
+		err = s.store.AddOwnerUser(nil, req.GroupId, req.UserId)
+	}
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+func (s *Server) apiRemoveUserFromGroup(w http.ResponseWriter, r *http.Request) {
+	var req userGroupStatus
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, "Invalid request body", http.StatusBadRequest)
+		return
+	}
+	status, err := convertStatus(req.Status)
+	if err != nil {
+		http.Error(w, "Invalid status", http.StatusBadRequest)
+		return
+	}
+	switch status {
+	case Member:
+		err = s.store.RemoveMemberUser(nil, req.GroupId, req.UserId)
+	case Owner:
+		err = s.store.RemoveOwnerUser(nil, req.GroupId, req.UserId)
+	}
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+type groupGroupStatus struct {
+	GroupId string `json:"groupId"`
+	OtherId string `json:"otherId"`
+	Status  string `json:"status"`
+}
+
+func (s *Server) apiAddGroupToGroup(w http.ResponseWriter, r *http.Request) {
+	var req groupGroupStatus
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, "Invalid request body", http.StatusBadRequest)
+		return
+	}
+	status, err := convertStatus(req.Status)
+	if err != nil {
+		http.Error(w, "Invalid status", http.StatusBadRequest)
+		return
+	}
+	switch status {
+	case Member:
+		err = s.store.AddMemberGroup(nil, req.GroupId, req.OtherId)
+	case Owner:
+		err = s.store.AddOwnerGroup(nil, req.GroupId, req.OtherId)
+	}
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+func (s *Server) apiRemoveGroupFromGroup(w http.ResponseWriter, r *http.Request) {
+	var req groupGroupStatus
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, "Invalid request body", http.StatusBadRequest)
+		return
+	}
+	status, err := convertStatus(req.Status)
+	if err != nil {
+		http.Error(w, "Invalid status", http.StatusBadRequest)
+		return
+	}
+	switch status {
+	case Member:
+		err = s.store.RemoveMemberGroup(nil, req.GroupId, req.OtherId)
+	case Owner:
+		err = s.store.RemoveOwnerGroup(nil, req.GroupId, req.OtherId)
+	}
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+}
+
+type getGroupsOwnedByRequest struct {
+	User string `json:"user"`
+}
+
+type getGroupsOwnedByResponse struct {
+	Groups []string `json:"groups"`
+}
+
+func (s *Server) apiGetUserOwnedGroups(w http.ResponseWriter, r *http.Request) {
+	var req getGroupsOwnedByRequest
+	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
+		http.Error(w, err.Error(), http.StatusBadRequest)
+		return
+	}
+	groups, err := s.store.GetGroupsUserOwns(nil, req.User)
+	if err != nil {
+		http.Error(w, err.Error(), http.StatusInternalServerError)
+		return
+	}
+	var resp getGroupsOwnedByResponse
+	for _, g := range groups {
+		resp.Groups = append(resp.Groups, g.Title)
+	}
+	if err := json.NewEncoder(w).Encode(resp); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
@@ -1342,7 +951,7 @@
 		http.Error(w, "PublicKey cannot be empty", http.StatusBadRequest)
 		return
 	}
-	if err := s.store.AddSSHKeyForUser(strings.ToLower(req.User), req.PublicKey); err != nil {
+	if err := s.store.AddUserPublicKey(nil, strings.ToLower(req.User), req.PublicKey); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
@@ -1381,17 +990,17 @@
 }
 
 func convertStatus(status string) (Status, error) {
-	switch status {
-	case "Owner":
+	switch strings.ToLower(status) {
+	case "owner":
 		return Owner, nil
-	case "Member":
+	case "member":
 		return Member, nil
 	default:
 		return Owner, fmt.Errorf("invalid status: %s", status)
 	}
 }
 
-func isValidGroupName(group string) error {
+func isValidGroupId(group string) error {
 	if strings.TrimSpace(group) == "" {
 		return fmt.Errorf("Group name can't be empty or contain only whitespaces")
 	}
@@ -1419,3 +1028,10 @@
 	}
 	log.Fatal(s.Start())
 }
+
+func normalizeGroupId(groupId string) string {
+	if strings.Contains(groupId, "/") && !strings.HasPrefix(groupId, "/") {
+		return fmt.Sprintf("/%s", groupId)
+	}
+	return groupId
+}
diff --git a/core/auth/memberships/memberships-tmpl/group.html b/core/auth/memberships/memberships-tmpl/group.html
index c927536..c3ff8c7 100644
--- a/core/auth/memberships/memberships-tmpl/group.html
+++ b/core/auth/memberships/memberships-tmpl/group.html
@@ -1,16 +1,20 @@
 {{ define "title" }}
-    Group - {{ .GroupName }}
+    Group - {{ .Title }}
 {{ end }}
 {{ define "content" }}
-{{- $parentGroupName := .GroupName }}
+{{- $parentGroupId := .GroupId }}
     <div>
-        <h2 class="headline">Group: {{ .GroupName }}</h2>
+        <h2 class="headline">Group: {{ .Title }}</h2>
         <p class="description">{{ .Description }}</p>
     </div>
     <hr class="divider">
-    <form action="/group/{{ .GroupName }}/add-user/" method="post">
+    <form action="/group/{{ .GroupId }}/add-user/" method="post">
         <fieldset class="grid first">
-            <input type="text" id="username" name="username" placeholder="username" required>
+            <select id="userId" aria-label="Select" name="userId" required>
+                {{- range .AllUsers }}
+                <option value="{{ .Id }}">{{ .Username }}</option>
+                {{- end }}
+            </select>
             <select id="status" name="status" required>
                 <option value="Member" selected>Member</option>
                 <option value="Owner">Owner</option>
@@ -18,21 +22,21 @@
             <button type="submit">Add Member</button>
         </fieldset>
     </form>
-    <form action="/group/{{ .GroupName }}/add-child-group" method="post">
+    <form action="/group/{{ .GroupId }}/add-child-group" method="post">
         <fieldset class="grid twoone">
-            <select id="child-group" aria-label="Select" name="child-group" required>
+            <select id="otherId" aria-label="Select" name="otherId" required>
                 {{- range .AllGroups }}
-                <option value="{{ .Name }}">{{ .Name }}</option>
+                <option value="{{ .Id }}">{{ .Title }}</option>
                 {{- end }}
             </select>
             <button type="submit">Create Child Group</button>
         </fieldset>
     </form>
-    <form action="/group/{{ .GroupName }}/add-owner-group" method="post">
+    <form action="/group/{{ .GroupId }}/add-owner-group" method="post">
         <fieldset class="grid twoone">
-            <select id="owner-group" aria-label="Select" name="owner-group" required>
+            <select id="otherId" aria-label="Select" name="otherId" required>
                 {{- range .AllGroups }}
-                <option value="{{ .Name }}">{{ .Name }}</option>
+                <option value="{{ .Id }}">{{ .Title }}</option>
                 {{- end }}
             </select>
             <button type="submit">Add Owner Group</button>
@@ -44,8 +48,8 @@
         {{- range .Owners }}
         <div>
             <fieldset role="group">
-            <a class="link-button" href="/user/{{ . }}" role="button">{{ . }}</a>
-            <form action="/group/{{ $parentGroupName }}/remove-owner/{{ . }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to revoke user <strong>{{ . }}</strong>'s ownership of the  <strong>{{ $parentGroupName }}</strong> group?">
+            <a class="link-button" href="/user/{{ .Id }}" role="button">{{ .Username }}</a>
+            <form action="/group/{{ $parentGroupId }}/remove-owner/{{ .Id }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to revoke user <strong>{{ .Username }}</strong>'s ownership of the  <strong>{{ $parentGroupId }}</strong> group?">
                 <button class="remove" type="submit" aria-label="Remove owner">
                     {{ template "svgIcon" }}
                 </button>
@@ -62,8 +66,8 @@
         {{- range .Members }}
         <div>
             <fieldset role="group">
-                <a class="link-button" href="/user/{{ . }}" role="button">{{ . }}</a>
-            <form action="/group/{{ $parentGroupName }}/remove-member/{{ . }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove user  <strong>{{ . }}</strong> user from  <strong>{{ $parentGroupName }}</strong> group?">
+                <a class="link-button" href="/user/{{ .Id }}" role="button">{{ .Username }}</a>
+            <form action="/group/{{ $parentGroupId }}/remove-member/{{ .Id }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove user  <strong>{{ .Username }}</strong> user from  <strong>{{ $parentGroupId }}</strong> group?">
                 <button class="remove" type="submit">
                     {{ template "svgIcon" }}
                 </button>
@@ -77,9 +81,9 @@
     <h3>Transitive Groups</h3>
     <div class="user-remove">
         {{- range .TransitiveGroups }}
-            <a class="link-button" href="/group/{{ .Name }}" role="button" 
+            <a class="link-button" href="/group/{{ .Id }}" role="button" 
                {{ if ne .Description "" }} data-tooltip="{{ .Description }}" data-placement="bottom" {{ end }}>
-               {{ .Name }}
+               {{ .Title }}
             </a>
         {{- end }}
     </div>
@@ -90,11 +94,11 @@
         {{- range .ChildGroups }}
         <div>
             <fieldset role="group">
-                <a class="link-button" href="/group/{{ .Name }}" role="button" 
+                <a class="link-button" href="/group/{{ .Id }}" role="button" 
                     {{ if ne .Description "" }} data-tooltip="{{ .Description }}" data-placement="bottom" {{ end }}>
-                    {{ .Name }}
+                    {{ .Title }}
                 </a>
-                <form action="/group/{{ $parentGroupName }}/remove-child-group/{{ .Name }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove group  <strong>{{ .Name }}</strong> as a child of the group  <strong>{{ $parentGroupName }}</strong>?">
+                <form action="/group/{{ $parentGroupId }}/remove-child-group/{{ .Id }}" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove group  <strong>{{ .Title }}</strong> as a child of the group  <strong>{{ $parentGroupId }}</strong>?">
                     <button class="remove" type="submit">
                         {{ template "svgIcon" }}
                     </button>
@@ -108,9 +112,9 @@
     <h3>Owner Groups</h3>
     <div class="user-remove">
         {{- range .OwnerGroups }}
-        <a class="link-button" href="/group/{{ .Name }}" role="button" 
+        <a class="link-button" href="/group/{{ .Id }}" role="button" 
             {{ if ne .Description "" }} data-tooltip="{{ .Description }}" data-placement="bottom" {{ end }}>
-            {{ .Name }}
+            {{ .Title }}
         </a>
         {{- end }}
     </div>
diff --git a/core/auth/memberships/memberships-tmpl/user.html b/core/auth/memberships/memberships-tmpl/user.html
index 562f27d..eda7eb5 100644
--- a/core/auth/memberships/memberships-tmpl/user.html
+++ b/core/auth/memberships/memberships-tmpl/user.html
@@ -1,11 +1,11 @@
 {{ define "title" }}
-    User - {{ .CurrentUser }}
+    User - {{ .User.Username }}
 {{ end }}
 {{- define "content" -}}
-    {{ $currentUser := .CurrentUser }}
+    {{ $currentUserId := .User.Id }}
     {{ $isLoggedInUser := .LoggedInUserPage}}
-    <h1 class="headline">User: {{ .CurrentUser }}</h1>
-    <p>{{ .Email }}</p>
+    <h1 class="headline">User: {{ .User.Username }}</h1>
+    <p>{{ .User.Email }}</p>
     <hr class="divider">
     <h3>SSH Public keys</h3>
     <div class="ssh-key-grid">
@@ -15,7 +15,7 @@
             {{ range .SSHPublicKeys }}
                 <div class="ssh-key-item">
                     {{ if $isLoggedInUser }}
-                        <form action="/user/{{ $currentUser }}/remove-ssh-key" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove SSH key?">
+                        <form action="/user/{{ $currentUserId }}/remove-ssh-key" method="post" class="remove-form" data-confirmation-message="Are you sure you want to remove SSH key?">
                             <input type="hidden" name="ssh-key" value="{{ . }}">
                             <button class="remove ssh-remove" type="submit">
                                 <div>{{ template "svgIcon" }}</div>
@@ -29,7 +29,7 @@
     </div>
     {{ if .LoggedInUserPage }}
     <hr class="divider">
-    <form action="/user/{{ .CurrentUser }}/ssh-key" method="post">
+    <form action="/user/{{ .User.Id }}/ssh-key" method="post">
         <fieldset class="grid twoone">
             <input type="text" id="ssh-hey" name="ssh-key" placeholder="Add SSH public key..." required>
             <button type="submit">Add SSH public key</button>
@@ -38,7 +38,8 @@
     <hr class="divider">
     <form action="/create-group" method="post">
         <fieldset class="grid first">
-            <input type="text" id="group-name" name="group-name" placeholder="Group name" required>
+            <input type="text" id="id" name="id" placeholder="Id" required>
+			<input type="text" id="title" name="title" placeholder="Title" required>
             <input type="text" id="description" name="description" placeholder="Description">
             <button type="submit">Create Group</button>
         </fieldset>
@@ -49,9 +50,9 @@
     <h3>Owner of groups</h3>
     <div class="user-remove">
         {{- range .OwnerGroups }}
-            <a href="/group/{{ .Name }}" role="button" 
+            <a href="/group/{{ .Id }}" role="button" 
                 {{ if ne .Description "" }} data-tooltip="{{ .Description }}" data-placement="bottom" {{ end }}>
-                {{ .Name }}
+                {{ .Title }}
             </a>
         {{- end }}
     </div>
@@ -60,9 +61,9 @@
     <h3>Direct member of groups</h3>
     <div class="user-remove">
         {{- range .MembershipGroups }}
-            <a href="/group/{{ .Name }}" role="button" 
+            <a href="/group/{{ .Id }}" role="button" 
                 {{ if ne .Description "" }} data-tooltip="{{ .Description }}" data-placement="bottom" {{ end }}>
-                {{ .Name }}
+                {{ .Title }}
             </a>
         {{- end }}
     </div>
@@ -71,9 +72,9 @@
     <h3>Transitive member of groups</h3>
     <div class="user-remove">
         {{- range .TransitiveGroups -}}
-            <a href="/group/{{ .Name }}" role="button" 
+            <a href="/group/{{ .Id }}" role="button" 
                {{ if ne .Description "" }} data-tooltip="{{ .Description }}" data-placement="bottom" {{ end }}>
-               {{ .Name }}
+               {{ .Title }}
             </a>
         {{- end }}
     </div>
diff --git a/core/auth/memberships/schema.sql b/core/auth/memberships/schema.sql
new file mode 100644
index 0000000..be7d9c3
--- /dev/null
+++ b/core/auth/memberships/schema.sql
@@ -0,0 +1,35 @@
+CREATE TABLE IF NOT EXISTS users (
+	   id TEXT PRIMARY KEY,
+	   username TEXT NOT NULL,
+	   email TEXT NOT NULL,
+	   UNIQUE(username),
+	   UNIQUE (email)
+);
+
+CREATE TABLE IF NOT EXISTS keys (
+	   user_id TEXT,
+	   public_key TEXT,
+	   UNIQUE (public_key),
+	   FOREIGN KEY(user_id) REFERENCES users(id)
+);
+
+CREATE TABLE IF NOT EXISTS groups (
+	   id TEXT PRIMARY KEY,
+	   title TEXT NOT NULL,
+	   description TEXT,
+	   external_id TEXT
+);
+
+CREATE TABLE IF NOT EXISTS memberships (
+	   id TEXT NOT NULL,
+	   membership_type TEXT CHECK(membership_type IN ('member', 'owner')) NOT NULL,
+	   member_type TEXT CHECK(member_type IN ('user', 'group')) NOT NULL,
+	   user_id TEXT,
+	   group_id TEXT,
+	   FOREIGN KEY(id) REFERENCES groups(id)
+	   FOREIGN KEY(user_id) REFERENCES users(id),
+	   FOREIGN KEY(group_id) REFERENCES groups(id),
+	   CHECK(user_id IS NULL OR group_id IS NULL),
+	   CHECK((member_type = 'user' AND user_id IS NOT NULL) OR (member_type = 'group' AND group_id IS NOT NULL)),
+	   UNIQUE (id, membership_type, member_type, user_id, group_id)
+);
diff --git a/core/auth/memberships/store.go b/core/auth/memberships/store.go
new file mode 100644
index 0000000..05b09bc
--- /dev/null
+++ b/core/auth/memberships/store.go
@@ -0,0 +1,690 @@
+package main
+
+import (
+	"database/sql"
+	_ "embed"
+	"fmt"
+	"strings"
+
+	"github.com/ncruces/go-sqlite3"
+)
+
+//go:embed schema.sql
+var schema string
+
+const (
+	ErrorUniqueConstraintViolation     = 2067
+	ErrorConstraintPrimaryKeyViolation = 1555
+)
+
+type scanner interface {
+	Scan(dest ...any) error
+}
+
+type Store interface {
+	// Initializes store with admin user and their groups.
+	Init(user User, groups []Group) error
+	CreateUser(tx *sql.Tx, user User) error
+	GetAllUsers(tx *sql.Tx) ([]User, error)
+	GetUser(tx *sql.Tx, id string) (User, error)
+	GetUsers(tx *sql.Tx, ids []string) ([]User, error)
+	CreateGroup(tx *sql.Tx, userId string, group Group) error
+	GetGroup(tx *sql.Tx, id string) (Group, error)
+	GetAllGroups(tx *sql.Tx) ([]Group, error)
+	AddMemberUser(tx *sql.Tx, groupId, userId string) error
+	AddOwnerUser(tx *sql.Tx, groupId, userId string) error
+	AddMemberGroup(tx *sql.Tx, groupId, otherId string) error
+	AddOwnerGroup(tx *sql.Tx, groupId, otherId string) error
+	GetMemberUsers(tx *sql.Tx, groupId string) ([]User, error)
+	GetOwnerUsers(tx *sql.Tx, groupId string) ([]User, error)
+	GetMemberGroups(tx *sql.Tx, groupId string) ([]Group, error)
+	GetOwnerGroups(tx *sql.Tx, groupId string) ([]Group, error)
+	RemoveMemberUser(tx *sql.Tx, groupId, userId string) error
+	RemoveOwnerUser(tx *sql.Tx, groupId, userId string) error
+	RemoveMemberGroup(tx *sql.Tx, groupId, otherId string) error
+	RemoveOwnerGroup(tx *sql.Tx, groupId, otherId string) error
+	GetGroupsUserCanActAs(tx *sql.Tx, userId string) ([]Group, error)
+	GetGroupsGroupCanActAs(tx *sql.Tx, groupId string) ([]Group, error)
+	GetGroupsUserOwns(tx *sql.Tx, userId string) ([]Group, error)
+	GetGroupsUserIsMemberOf(tx *sql.Tx, userId string) ([]Group, error)
+	GetUserPublicKeys(tx *sql.Tx, userId string) ([]string, error)
+	AddUserPublicKey(tx *sql.Tx, userId, publicKey string) error
+	RemoveUserPublicKey(tx *sql.Tx, userId, publicKey string) error
+}
+
+type SQLiteStore struct {
+	db *sql.DB
+}
+
+func NewSQLiteStore(db *sql.DB) (*SQLiteStore, error) {
+	_, err := db.Exec(schema)
+	if err != nil {
+		return nil, err
+	}
+	return &SQLiteStore{db: db}, nil
+}
+
+func (s *SQLiteStore) Init(user User, groups []Group) error {
+	tx, err := s.db.Begin()
+	if err != nil {
+		return err
+	}
+	defer tx.Rollback()
+	row := tx.QueryRow("SELECT COUNT(*) FROM groups")
+	var count int
+	if err := row.Scan(&count); err != nil {
+		return err
+	}
+	if count != 0 {
+		return fmt.Errorf("Store already initialised")
+	}
+	if err := s.CreateUser(tx, user); err != nil {
+		return err
+	}
+	for _, g := range groups {
+		if err := s.CreateGroup(tx, user.Id, g); err != nil {
+			return err
+		}
+		if err := s.AddMemberUser(tx, g.Id, user.Id); err != nil {
+			return err
+		}
+	}
+	return tx.Commit()
+}
+
+func (s *SQLiteStore) CreateUser(tx *sql.Tx, user User) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "INSERT INTO users (id, username, email) VALUES (?, ?, ?)"
+	_, err = tx.Exec(query, user.Id, user.Username, user.Email)
+	return
+}
+
+func (s *SQLiteStore) scanUser(row scanner) (User, error) {
+	var ret User
+	if err := row.Scan(&ret.Id, &ret.Username, &ret.Email); err != nil {
+		return User{}, err
+	}
+	return ret, nil
+}
+
+func (s *SQLiteStore) scanUsers(rows *sql.Rows) ([]User, error) {
+	var ret []User
+	for rows.Next() {
+		if u, err := s.scanUser(rows); err != nil {
+			return nil, err
+		} else {
+			ret = append(ret, u)
+		}
+	}
+	if err := rows.Err(); err != nil {
+		return nil, err
+	}
+	return ret, nil
+}
+
+func (s *SQLiteStore) scanGroup(row scanner) (Group, error) {
+	var ret Group
+	if err := row.Scan(&ret.Id, &ret.Title, &ret.Description); err != nil {
+		return Group{}, err
+	}
+	return ret, nil
+}
+
+func (s *SQLiteStore) scanGroups(rows *sql.Rows) ([]Group, error) {
+	var ret []Group
+	for rows.Next() {
+		if g, err := s.scanGroup(rows); err != nil {
+			return nil, err
+		} else {
+			ret = append(ret, g)
+		}
+	}
+	if err := rows.Err(); err != nil {
+		return nil, err
+	}
+	return ret, nil
+}
+
+func (s *SQLiteStore) GetAllUsers(tx *sql.Tx) (ret []User, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "SELECT id, username, email FROM users"
+	var rows *sql.Rows
+	if rows, err = tx.Query(query); err == nil {
+		ret, err = s.scanUsers(rows)
+	}
+	return
+}
+
+func (s *SQLiteStore) GetUser(tx *sql.Tx, id string) (ret User, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "SELECT id, username, email FROM users WHERE id = ?"
+	row := tx.QueryRow(query, id)
+	ret, err = s.scanUser(row)
+	return
+}
+
+func (s *SQLiteStore) GetUsers(tx *sql.Tx, ids []string) (ret []User, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	idPlaceholders := make([]string, len(ids))
+	idParams := make([]any, len(ids))
+	for i, id := range ids {
+		idPlaceholders[i] = "?"
+		idParams[i] = id
+	}
+	query := fmt.Sprintf("SELECT id, username, email FROM users WHERE id IN (%s)", strings.Join(idPlaceholders, ", "))
+	var rows *sql.Rows
+	if rows, err = tx.Query(query, idParams...); err == nil {
+		ret, err = s.scanUsers(rows)
+	}
+	return
+}
+
+func (s *SQLiteStore) CreateGroup(tx *sql.Tx, userId string, group Group) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "INSERT INTO groups (id, title, description) VALUES (?, ?, ?)"
+	if _, err = tx.Exec(query, group.Id, group.Title, group.Description); err != nil {
+		sqliteErr, ok := err.(*sqlite3.Error)
+		if ok && sqliteErr.ExtendedCode() == ErrorConstraintPrimaryKeyViolation {
+			err = fmt.Errorf("Group with id %s already exists", group.Id)
+		}
+		return
+	}
+	err = s.addUser(tx, group.Id, userId, "owner")
+	return
+}
+
+func (s *SQLiteStore) GetGroup(tx *sql.Tx, id string) (ret Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "SELECT id, title, description FROM groups WHERE id = ?"
+	row := tx.QueryRow(query, id)
+	ret, err = s.scanGroup(row)
+	return
+}
+func (s *SQLiteStore) GetAllGroups(tx *sql.Tx) (ret []Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "SELECT id, title, description FROM groups"
+	var rows *sql.Rows
+	if rows, err = tx.Query(query); err == nil {
+		ret, err = s.scanGroups(rows)
+	}
+	return
+}
+
+func (s *SQLiteStore) addUser(tx *sql.Tx, groupId, userId, membershipType string) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "INSERT INTO memberships (id, membership_type, member_type, user_id) VALUES (?, ?, ?, ?)"
+	_, err = tx.Exec(query, groupId, membershipType, "user", userId)
+	return
+}
+
+func (s *SQLiteStore) addGroup(tx *sql.Tx, groupId, otherId, membershipType string) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "INSERT INTO memberships (id, membership_type, member_type, group_id) VALUES (?, ?, ?, ?)"
+	_, err = tx.Exec(query, groupId, membershipType, "group", otherId)
+	return
+}
+
+func (s *SQLiteStore) removeUser(tx *sql.Tx, groupId, userId, membershipType string) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "DELETE FROM memberships WHERE id = ? AND membership_type = ? AND member_type = ? AND user_id = ?"
+	_, err = tx.Exec(query, groupId, membershipType, "user", userId)
+	return
+}
+
+func (s *SQLiteStore) removeGroup(tx *sql.Tx, groupId, otherId, membershipType string) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "DELETE FROM memberships WHERE id = ? AND membership_type = ? AND member_type = ? AND group_id = ?"
+	_, err = tx.Exec(query, groupId, membershipType, "group", otherId)
+	return
+}
+
+func (s *SQLiteStore) getUsers(tx *sql.Tx, groupId, membershipType string) (ret []User, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := `
+SELECT u.id, u.username, u.email
+FROM users u
+JOIN memberships m
+ON u.id = m.user_id
+WHERE m.id = ? AND membership_type = ? AND member_type = ?
+`
+	var rows *sql.Rows
+	rows, err = tx.Query(query, groupId, membershipType, "user")
+	if err != nil {
+		return
+	}
+	ret, err = s.scanUsers(rows)
+	return
+}
+
+func (s *SQLiteStore) getGroups(tx *sql.Tx, groupId, membershipType string) (ret []Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := `
+SELECT g.id, g.title, g.description
+FROM groups AS g
+JOIN memberships AS m
+ON g.id = m.group_id
+WHERE m.id = ? AND m.membership_type = ? AND m.member_type = ?`
+	var rows *sql.Rows
+	if rows, err = tx.Query(query, groupId, membershipType, "group"); err == nil {
+		ret, err = s.scanGroups(rows)
+	}
+	return
+}
+
+func (s *SQLiteStore) AddMemberUser(tx *sql.Tx, groupId, userId string) error {
+	return s.addUser(tx, groupId, userId, "member")
+}
+
+func (s *SQLiteStore) AddOwnerUser(tx *sql.Tx, groupId, userId string) error {
+	return s.addUser(tx, groupId, userId, "owner")
+}
+
+func (s *SQLiteStore) AddMemberGroup(tx *sql.Tx, groupId, otherId string) error {
+	return s.addGroup(tx, groupId, otherId, "member")
+}
+
+func (s *SQLiteStore) AddOwnerGroup(tx *sql.Tx, groupId, otherId string) error {
+	return s.addGroup(tx, groupId, otherId, "owner")
+}
+
+func (s *SQLiteStore) GetMemberUsers(tx *sql.Tx, groupId string) ([]User, error) {
+	return s.getUsers(tx, groupId, "member")
+}
+
+func (s *SQLiteStore) GetOwnerUsers(tx *sql.Tx, groupId string) ([]User, error) {
+	return s.getUsers(tx, groupId, "owner")
+}
+
+func (s *SQLiteStore) GetMemberGroups(tx *sql.Tx, groupId string) ([]Group, error) {
+	return s.getGroups(tx, groupId, "member")
+}
+
+func (s *SQLiteStore) GetOwnerGroups(tx *sql.Tx, groupId string) ([]Group, error) {
+	return s.getGroups(tx, groupId, "owner")
+}
+
+func (s *SQLiteStore) RemoveMemberUser(tx *sql.Tx, groupId, userId string) error {
+	return s.removeUser(tx, groupId, userId, "member")
+}
+
+func (s *SQLiteStore) RemoveOwnerUser(tx *sql.Tx, groupId, userId string) error {
+	return s.removeUser(tx, groupId, userId, "owner")
+}
+
+func (s *SQLiteStore) RemoveMemberGroup(tx *sql.Tx, groupId, otherId string) error {
+	return s.removeGroup(tx, groupId, otherId, "member")
+}
+
+func (s *SQLiteStore) RemoveOwnerGroup(tx *sql.Tx, groupId, otherId string) error {
+	return s.removeGroup(tx, groupId, otherId, "owner")
+}
+
+func (s *SQLiteStore) traverseGroups(tx *sql.Tx, groups ...Group) ([]Group, error) {
+	seen := map[string]struct{}{}
+	for _, g := range groups {
+		seen[g.Id] = struct{}{}
+	}
+	for i := 0; i < len(groups); i++ {
+		g := groups[i]
+		parents, err := s.getGroupGroups(tx, g.Id, "member")
+		if err != nil {
+			return nil, err
+		}
+		for _, p := range parents {
+			if _, ok := seen[p.Id]; !ok {
+				groups = append(groups, p)
+				seen[p.Id] = struct{}{}
+			}
+		}
+	}
+	return groups, nil
+}
+
+func (s *SQLiteStore) GetGroupsUserCanActAs(tx *sql.Tx, userId string) (ret []Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	var memberOf []Group
+	memberOf, err = s.GetGroupsUserIsMemberOf(tx, userId)
+	if err != nil {
+		return
+	}
+	ret, err = s.traverseGroups(tx, memberOf...)
+	return
+}
+
+func (s *SQLiteStore) GetGroupsGroupCanActAs(tx *sql.Tx, groupId string) (ret []Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	var g Group
+	g, err = s.GetGroup(tx, groupId)
+	if err != nil {
+		return
+	}
+	var groups []Group
+	if groups, err = s.traverseGroups(tx, g); err == nil {
+		ret = groups[1:]
+	}
+	return
+}
+
+func (s *SQLiteStore) getUserGroups(tx *sql.Tx, userId, membershipType string) (ret []Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			}
+			if err != nil {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := `
+SELECT g.id, g.title, g.description
+FROM groups AS g
+JOIN memberships AS m
+ON g.id = m.id
+WHERE m.user_id = ? AND m.membership_type = ? AND m.member_type = ?`
+	var rows *sql.Rows
+	if rows, err = tx.Query(query, userId, membershipType, "user"); err == nil {
+		ret, err = s.scanGroups(rows)
+	}
+	return
+}
+
+func (s *SQLiteStore) getGroupGroups(tx *sql.Tx, groupId, membershipType string) (ret []Group, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := `
+SELECT g.id, g.title, g.description
+FROM groups AS g
+JOIN memberships AS m
+ON g.id = m.id
+WHERE m.group_id = ? AND m.membership_type = ? AND m.member_type = ?`
+	var rows *sql.Rows
+	if rows, err = tx.Query(query, groupId, membershipType, "group"); err == nil {
+		ret, err = s.scanGroups(rows)
+	}
+	return
+}
+
+func (s *SQLiteStore) GetGroupsUserOwns(tx *sql.Tx, userId string) ([]Group, error) {
+	return s.getUserGroups(tx, userId, "owner")
+}
+
+func (s *SQLiteStore) GetGroupsUserIsMemberOf(tx *sql.Tx, userId string) ([]Group, error) {
+	return s.getUserGroups(tx, userId, "member")
+}
+
+func (s *SQLiteStore) AddUserPublicKey(tx *sql.Tx, userId, publicKey string) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "INSERT INTO keys (user_id, public_key) VALUES (?, ?)"
+	_, err = tx.Exec(query, userId, publicKey)
+	return
+}
+
+func (s *SQLiteStore) GetUserPublicKeys(tx *sql.Tx, userId string) (ret []string, err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "SELECT public_key FROM keys WHERE user_id = ?"
+	var rows *sql.Rows
+	if rows, err = tx.Query(query, userId); err != nil {
+		return
+	}
+	defer rows.Close()
+
+	for rows.Next() {
+		var publicKey string
+		if err = rows.Scan(&publicKey); err != nil {
+			return
+		}
+		ret = append(ret, publicKey)
+	}
+	err = rows.Err()
+	return
+}
+
+func (s *SQLiteStore) RemoveUserPublicKey(tx *sql.Tx, userId, publicKey string) (err error) {
+	if tx == nil {
+		tx, err = s.db.Begin()
+		if err != nil {
+			return
+		}
+		defer func() {
+			if err == nil {
+				err = tx.Commit()
+			} else {
+				tx.Rollback()
+			}
+		}()
+	}
+	query := "DELETE FROM keys WHERE user_id = ? AND  public_key = ?"
+	_, err = tx.Exec(query, userId, publicKey)
+	return
+}
diff --git a/core/auth/memberships/store_test.go b/core/auth/memberships/store_test.go
index aba707c..b7be081 100644
--- a/core/auth/memberships/store_test.go
+++ b/core/auth/memberships/store_test.go
@@ -2,19 +2,20 @@
 
 import (
 	"database/sql"
-	"encoding/json"
-	"net/http"
-	"net/http/httptest"
-	"reflect"
-	"sync"
+	"strings"
 	"testing"
 
-	"github.com/gorilla/mux"
 	_ "github.com/ncruces/go-sqlite3/driver"
 	_ "github.com/ncruces/go-sqlite3/embed"
 )
 
-func TestInitSuccess(t *testing.T) {
+var initGroups = []Group{
+	{Id: "admin", Title: "Admin", Description: "Admin group"},
+	{Id: "all", Title: "All", Description: "All members"},
+}
+
+// Helper function to create a new in-memory SQLite store for testing
+func createTestStore(t *testing.T) Store {
 	db, err := sql.Open("sqlite3", ":memory:")
 	if err != nil {
 		t.Fatal(err)
@@ -23,377 +24,1008 @@
 	if err != nil {
 		t.Fatal(err)
 	}
-	if err := store.Init("admin", "admin@admin", []string{"admin", "all"}); err != nil {
+	return store
+}
+
+// Helper function to create a store with initialized data
+func createInitializedStore(t *testing.T) Store {
+	store := createTestStore(t)
+	adminUser := User{Id: "1", Username: "admin", Email: "admin@admin.com"}
+	if err := store.Init(adminUser, initGroups); err != nil {
 		t.Fatal(err)
 	}
-	groups, err := store.GetGroupsOwnedBy("admin")
+	return store
+}
+
+func TestNewSQLiteStore(t *testing.T) {
+	db, err := sql.Open("sqlite3", ":memory:")
 	if err != nil {
 		t.Fatal(err)
 	}
-	if len(groups) != 2 {
-		t.Fatalf("Expected two groups, got: %s", groups)
-	}
-	groups, err = store.GetGroupsUserBelongsTo("admin")
+	defer db.Close()
+
+	store, err := NewSQLiteStore(db)
 	if err != nil {
 		t.Fatal(err)
 	}
-	if len(groups) != 2 {
-		t.Fatalf("Expected two groups, got: %s", groups)
+	if store == nil {
+		t.Fatal("expected store to be non-nil")
 	}
 }
 
-func TestInitFailure(t *testing.T) {
-	db, err := sql.Open("sqlite3", ":memory:")
+func TestInit(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createTestStore(t)
+		adminUser := User{Id: "1", Username: "admin", Email: "admin@admin.com"}
+		err := store.Init(adminUser, initGroups)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// Verify user was created
+		user, err := store.GetUser(nil, "1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if user.Username != "admin" || user.Email != "admin@admin.com" {
+			t.Fatalf("unexpected user: %+v", user)
+		}
+
+		// Verify groups were created
+		allGroups, err := store.GetAllGroups(nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(allGroups) != 2 {
+			t.Fatalf("expected 2 groups, got %d", len(allGroups))
+		}
+
+		// Verify user is member of both groups
+		memberGroups, err := store.GetGroupsUserIsMemberOf(nil, "1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(memberGroups) != 2 {
+			t.Fatalf("expected user to be member of 2 groups, got %d", len(memberGroups))
+		}
+	})
+
+	t.Run("already_initialized", func(t *testing.T) {
+		store := createInitializedStore(t)
+		user2 := User{Id: "2", Username: "user2", Email: "user2@test.com"}
+		err := store.Init(user2, []Group{})
+		if err == nil || !strings.Contains(err.Error(), "already initialised") {
+			t.Fatalf("expected 'already initialised' error, got: %v", err)
+		}
+	})
+}
+
+func TestCreateUser(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createTestStore(t)
+		user := User{Id: "user1", Username: "testuser", Email: "test@test.com"}
+		err := store.CreateUser(nil, user)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		retrievedUser, err := store.GetUser(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if retrievedUser.Id != "user1" || retrievedUser.Username != "testuser" || retrievedUser.Email != "test@test.com" {
+			t.Fatalf("unexpected user: %+v", retrievedUser)
+		}
+	})
+
+	t.Run("with_transaction", func(t *testing.T) {
+		store := createTestStore(t)
+		db := store.(*SQLiteStore).db
+		tx, err := db.Begin()
+		if err != nil {
+			t.Fatal(err)
+		}
+		defer tx.Rollback()
+
+		user := User{Id: "user1", Username: "testuser", Email: "test@test.com"}
+		err = store.CreateUser(tx, user)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if err := tx.Commit(); err != nil {
+			t.Fatal(err)
+		}
+
+		retrievedUser, err := store.GetUser(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if retrievedUser.Username != "testuser" {
+			t.Fatalf("unexpected username: %s", retrievedUser.Username)
+		}
+	})
+
+	t.Run("duplicate_id", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "testuser1", Email: "test1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		user2 := User{Id: "user1", Username: "testuser2", Email: "test2@test.com"}
+		err = store.CreateUser(nil, user2)
+		if err == nil {
+			t.Fatal("expected error for duplicate user ID")
+		}
+	})
+
+	t.Run("duplicate_username", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "testuser", Email: "test1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		user2 := User{Id: "user2", Username: "testuser", Email: "test2@test.com"}
+		err = store.CreateUser(nil, user2)
+		if err == nil {
+			t.Fatal("expected error for duplicate username")
+		}
+	})
+
+	t.Run("duplicate_email", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "testuser1", Email: "test@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		user2 := User{Id: "user2", Username: "testuser2", Email: "test@test.com"}
+		err = store.CreateUser(nil, user2)
+		if err == nil {
+			t.Fatal("expected error for duplicate email")
+		}
+	})
+}
+
+func TestGetUser(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createTestStore(t)
+		user := User{Id: "user1", Username: "testuser", Email: "test@test.com"}
+		err := store.CreateUser(nil, user)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		retrievedUser, err := store.GetUser(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if retrievedUser.Id != "user1" || retrievedUser.Username != "testuser" || retrievedUser.Email != "test@test.com" {
+			t.Fatalf("unexpected user: %+v", retrievedUser)
+		}
+	})
+
+	t.Run("not_found", func(t *testing.T) {
+		store := createTestStore(t)
+		_, err := store.GetUser(nil, "nonexistent")
+		if err == nil {
+			t.Fatal("expected error for nonexistent user")
+		}
+	})
+}
+
+func TestGetAllUsers(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create test users
+	users := []User{
+		{Id: "user1", Username: "testuser1", Email: "test1@test.com"},
+		{Id: "user2", Username: "testuser2", Email: "test2@test.com"},
+		{Id: "user3", Username: "testuser3", Email: "test3@test.com"},
+	}
+
+	for _, u := range users {
+		err := store.CreateUser(nil, u)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	allUsers, err := store.GetAllUsers(nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	store, err := NewSQLiteStore(db)
+	if len(allUsers) != 3 {
+		t.Fatalf("expected 3 users, got %d", len(allUsers))
+	}
+}
+
+func TestGetUsers(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create test users
+	users := []User{
+		{Id: "user1", Username: "testuser1", Email: "test1@test.com"},
+		{Id: "user2", Username: "testuser2", Email: "test2@test.com"},
+		{Id: "user3", Username: "testuser3", Email: "test3@test.com"},
+	}
+
+	for _, u := range users {
+		err := store.CreateUser(nil, u)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	selectedUsers, err := store.GetUsers(nil, []string{"user1", "user3"})
 	if err != nil {
 		t.Fatal(err)
 	}
-	_, err = db.Exec(`
-        INSERT INTO groups (name, description)
-        VALUES
-            ('a', 'xxx'),
-            ('b', 'yyy');
-        `)
+	if len(selectedUsers) != 2 {
+		t.Fatalf("expected 2 users, got %d", len(selectedUsers))
+	}
+
+	userIds := make(map[string]bool)
+	for _, u := range selectedUsers {
+		userIds[u.Id] = true
+	}
+	if !userIds["user1"] || !userIds["user3"] {
+		t.Fatal("unexpected users returned")
+	}
+}
+
+func TestCreateGroup(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createTestStore(t)
+		owner := User{Id: "owner1", Username: "owner", Email: "owner@test.com"}
+		err := store.CreateUser(nil, owner)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
+		err = store.CreateGroup(nil, "owner1", group)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		retrievedGroup, err := store.GetGroup(nil, "testgroup")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if retrievedGroup.Id != group.Id || retrievedGroup.Title != group.Title {
+			t.Fatalf("unexpected group: %+v", retrievedGroup)
+		}
+
+		// Verify owner was added
+		owners, err := store.GetOwnerUsers(nil, "testgroup")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(owners) != 1 || owners[0].Id != "owner1" {
+			t.Fatalf("expected owner1 to be group owner, got: %+v", owners)
+		}
+	})
+
+	t.Run("duplicate_id", func(t *testing.T) {
+		store := createTestStore(t)
+		owner := User{Id: "owner1", Username: "owner", Email: "owner@test.com"}
+		err := store.CreateUser(nil, owner)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
+		err = store.CreateGroup(nil, "owner1", group)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		err = store.CreateGroup(nil, "owner1", group)
+		if err == nil || !strings.Contains(err.Error(), "already exists") {
+			t.Fatalf("expected 'already exists' error, got: %v", err)
+		}
+	})
+}
+
+func TestGetGroup(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createInitializedStore(t)
+		group, err := store.GetGroup(nil, "admin")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if group.Id != "admin" || group.Title != "Admin" {
+			t.Fatalf("unexpected group: %+v", group)
+		}
+	})
+
+	t.Run("not_found", func(t *testing.T) {
+		store := createTestStore(t)
+		_, err := store.GetGroup(nil, "nonexistent")
+		if err == nil {
+			t.Fatal("expected error for nonexistent group")
+		}
+	})
+}
+
+func TestGetAllGroups(t *testing.T) {
+	store := createInitializedStore(t)
+	groups, err := store.GetAllGroups(nil)
 	if err != nil {
 		t.Fatal(err)
 	}
-	err = store.Init("admin", "admin", []string{"admin", "all"})
+	if len(groups) != 2 {
+		t.Fatalf("expected 2 groups, got %d", len(groups))
+	}
+}
+
+func TestAddMemberUser(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create users and group
+	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+	err := store.CreateUser(nil, user1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err = store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
+	err = store.CreateGroup(nil, "owner1", group)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = store.AddMemberUser(nil, "testgroup", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	members, err := store.GetMemberUsers(nil, "testgroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(members) != 1 || members[0].Id != "user1" {
+		t.Fatalf("expected user1 to be member, got: %+v", members)
+	}
+}
+
+func TestAddOwnerUser(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create users and group
+	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+	err := store.CreateUser(nil, user1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err = store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
+	err = store.CreateGroup(nil, "owner1", group)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = store.AddOwnerUser(nil, "testgroup", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	owners, err := store.GetOwnerUsers(nil, "testgroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Should have 2 owners now (original owner1 + user1)
+	if len(owners) != 2 {
+		t.Fatalf("expected 2 owners, got %d", len(owners))
+	}
+
+	ownerIds := make(map[string]bool)
+	for _, owner := range owners {
+		ownerIds[owner.Id] = true
+	}
+	if !ownerIds["owner1"] || !ownerIds["user1"] {
+		t.Fatal("expected both owner1 and user1 to be owners")
+	}
+}
+
+func TestAddMemberGroup(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create owner and groups
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err := store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
+	err = store.CreateGroup(nil, "owner1", parentGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+	childGroup := Group{Id: "child", Title: "Child Group", Description: "Child group"}
+	err = store.CreateGroup(nil, "owner1", childGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = store.AddMemberGroup(nil, "parent", "child")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	memberGroups, err := store.GetMemberGroups(nil, "parent")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(memberGroups) != 1 || memberGroups[0].Id != "child" {
+		t.Fatalf("expected child to be member group, got: %+v", memberGroups)
+	}
+}
+
+func TestAddOwnerGroup(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create owner and groups
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err := store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
+	err = store.CreateGroup(nil, "owner1", parentGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ownerGroup := Group{Id: "ownergroup", Title: "Owner Group", Description: "Owner group"}
+	err = store.CreateGroup(nil, "owner1", ownerGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	err = store.AddOwnerGroup(nil, "parent", "ownergroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	ownerGroups, err := store.GetOwnerGroups(nil, "parent")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(ownerGroups) != 1 || ownerGroups[0].Id != "ownergroup" {
+		t.Fatalf("expected ownergroup to be owner group, got: %+v", ownerGroups)
+	}
+}
+
+func TestRemoveMemberUser(t *testing.T) {
+	store := createTestStore(t)
+
+	// Setup: create user, owner, and group, then add user as member
+	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+	err := store.CreateUser(nil, user1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err = store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
+	err = store.CreateGroup(nil, "owner1", group)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddMemberUser(nil, "testgroup", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Test removal
+	err = store.RemoveMemberUser(nil, "testgroup", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	members, err := store.GetMemberUsers(nil, "testgroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(members) != 0 {
+		t.Fatalf("expected no members after removal, got: %+v", members)
+	}
+}
+
+func TestRemoveOwnerUser(t *testing.T) {
+	store := createTestStore(t)
+
+	// Setup: create users, group, and add second user as owner
+	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+	err := store.CreateUser(nil, user1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err = store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	group := Group{Id: "testgroup", Title: "Test Group", Description: "A test group"}
+	err = store.CreateGroup(nil, "owner1", group)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddOwnerUser(nil, "testgroup", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Test removal
+	err = store.RemoveOwnerUser(nil, "testgroup", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	owners, err := store.GetOwnerUsers(nil, "testgroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(owners) != 1 || owners[0].Id != "owner1" {
+		t.Fatalf("expected only owner1 to remain, got: %+v", owners)
+	}
+}
+
+func TestRemoveMemberGroup(t *testing.T) {
+	store := createTestStore(t)
+
+	// Setup: create groups and add one as member of the other
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err := store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
+	err = store.CreateGroup(nil, "owner1", parentGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+	childGroup := Group{Id: "child", Title: "Child Group", Description: "Child group"}
+	err = store.CreateGroup(nil, "owner1", childGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddMemberGroup(nil, "parent", "child")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Test removal
+	err = store.RemoveMemberGroup(nil, "parent", "child")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	memberGroups, err := store.GetMemberGroups(nil, "parent")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(memberGroups) != 0 {
+		t.Fatalf("expected no member groups after removal, got: %+v", memberGroups)
+	}
+}
+
+func TestRemoveOwnerGroup(t *testing.T) {
+	store := createTestStore(t)
+
+	// Setup: create groups and add one as owner of the other
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err := store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	parentGroup := Group{Id: "parent", Title: "Parent Group", Description: "Parent group"}
+	err = store.CreateGroup(nil, "owner1", parentGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+	ownerGroup := Group{Id: "ownergroup", Title: "Owner Group", Description: "Owner group"}
+	err = store.CreateGroup(nil, "owner1", ownerGroup)
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddOwnerGroup(nil, "parent", "ownergroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Test removal
+	err = store.RemoveOwnerGroup(nil, "parent", "ownergroup")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	ownerGroups, err := store.GetOwnerGroups(nil, "parent")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(ownerGroups) != 0 {
+		t.Fatalf("expected no owner groups after removal, got: %+v", ownerGroups)
+	}
+}
+
+func TestGetGroupsUserOwns(t *testing.T) {
+	store := createInitializedStore(t)
+	groups, err := store.GetGroupsUserOwns(nil, "1")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(groups) != 2 {
+		t.Fatalf("expected 2 groups owned by user 1, got %d", len(groups))
+	}
+}
+
+func TestGetGroupsUserIsMemberOf(t *testing.T) {
+	store := createInitializedStore(t)
+	groups, err := store.GetGroupsUserIsMemberOf(nil, "1")
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(groups) != 2 {
+		t.Fatalf("expected user 1 to be member of 2 groups, got %d", len(groups))
+	}
+}
+
+func TestGetGroupsUserCanActAs(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create complex hierarchy: user1 -> groupA -> groupB -> groupC
+	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+	err := store.CreateUser(nil, user1)
+	if err != nil {
+		t.Fatal(err)
+	}
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err = store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	groups := []Group{
+		{Id: "groupA", Title: "Group A", Description: "Group A"},
+		{Id: "groupB", Title: "Group B", Description: "Group B"},
+		{Id: "groupC", Title: "Group C", Description: "Group C"},
+	}
+
+	for _, g := range groups {
+		err = store.CreateGroup(nil, "owner1", g)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	// Build hierarchy: user1 member of groupA, groupA member of groupB, groupB member of groupC
+	err = store.AddMemberUser(nil, "groupA", "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddMemberGroup(nil, "groupB", "groupA")
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddMemberGroup(nil, "groupC", "groupB")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// user1 should be able to act as groupA, groupB, and groupC
+	canActAs, err := store.GetGroupsUserCanActAs(nil, "user1")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(canActAs) != 3 {
+		t.Fatalf("expected user1 to act as 3 groups, got %d", len(canActAs))
+	}
+
+	groupIds := make(map[string]bool)
+	for _, g := range canActAs {
+		groupIds[g.Id] = true
+	}
+	if !groupIds["groupA"] || !groupIds["groupB"] || !groupIds["groupC"] {
+		t.Fatal("expected user1 to act as groupA, groupB, and groupC")
+	}
+}
+
+func TestGetGroupsGroupCanActAs(t *testing.T) {
+	store := createTestStore(t)
+
+	// Create hierarchy: groupA -> groupB -> groupC
+	owner1 := User{Id: "owner1", Username: "owner1", Email: "owner1@test.com"}
+	err := store.CreateUser(nil, owner1)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	groups := []Group{
+		{Id: "groupA", Title: "Group A", Description: "Group A"},
+		{Id: "groupB", Title: "Group B", Description: "Group B"},
+		{Id: "groupC", Title: "Group C", Description: "Group C"},
+	}
+
+	for _, g := range groups {
+		err = store.CreateGroup(nil, "owner1", g)
+		if err != nil {
+			t.Fatal(err)
+		}
+	}
+
+	// Build hierarchy: groupA member of groupB, groupB member of groupC
+	err = store.AddMemberGroup(nil, "groupB", "groupA")
+	if err != nil {
+		t.Fatal(err)
+	}
+	err = store.AddMemberGroup(nil, "groupC", "groupB")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// groupA should be able to act as groupB and groupC (but not itself)
+	canActAs, err := store.GetGroupsGroupCanActAs(nil, "groupA")
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(canActAs) != 2 {
+		t.Fatalf("expected groupA to act as 2 groups, got %d", len(canActAs))
+	}
+
+	groupIds := make(map[string]bool)
+	for _, g := range canActAs {
+		groupIds[g.Id] = true
+	}
+	if !groupIds["groupB"] || !groupIds["groupC"] {
+		t.Fatal("expected groupA to act as groupB and groupC")
+	}
+}
+
+func TestAddUserPublicKey(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
+		err = store.AddUserPublicKey(nil, "user1", publicKey)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// Verify the key was added
+		keys, err := store.GetUserPublicKeys(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(keys) != 1 || keys[0] != publicKey {
+			t.Fatalf("expected 1 key, got %d: %v", len(keys), keys)
+		}
+	})
+
+	t.Run("duplicate_key", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
+		err = store.AddUserPublicKey(nil, "user1", publicKey)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// Adding the same key again should fail
+		err = store.AddUserPublicKey(nil, "user1", publicKey)
+		if err == nil {
+			t.Fatal("expected error for duplicate public key")
+		}
+	})
+
+	t.Run("nonexistent_user", func(t *testing.T) {
+		store := createTestStore(t)
+		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
+		err := store.AddUserPublicKey(nil, "nonexistent", publicKey)
+		if err == nil {
+			t.Fatal("expected error for nonexistent user")
+		}
+	})
+}
+
+func TestGetUserPublicKeys(t *testing.T) {
+	t.Run("success_multiple_keys", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		keys := []string{
+			"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ1... user1@example.com",
+			"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ2... user1@work.com",
+			"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI... user1@laptop",
+		}
+
+		// Add multiple keys
+		for _, key := range keys {
+			err = store.AddUserPublicKey(nil, "user1", key)
+			if err != nil {
+				t.Fatal(err)
+			}
+		}
+
+		// Retrieve all keys
+		retrievedKeys, err := store.GetUserPublicKeys(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		if len(retrievedKeys) != len(keys) {
+			t.Fatalf("expected %d keys, got %d", len(keys), len(retrievedKeys))
+		}
+
+		// Verify all keys are present
+		keyMap := make(map[string]bool)
+		for _, key := range retrievedKeys {
+			keyMap[key] = true
+		}
+		for _, expectedKey := range keys {
+			if !keyMap[expectedKey] {
+				t.Fatalf("expected key not found: %s", expectedKey)
+			}
+		}
+	})
+
+	t.Run("no_keys", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		keys, err := store.GetUserPublicKeys(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(keys) != 0 {
+			t.Fatalf("expected 0 keys for user with no keys, got %d", len(keys))
+		}
+	})
+
+	t.Run("nonexistent_user", func(t *testing.T) {
+		store := createTestStore(t)
+		keys, err := store.GetUserPublicKeys(nil, "nonexistent")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(keys) != 0 {
+			t.Fatalf("expected 0 keys for nonexistent user, got %d", len(keys))
+		}
+	})
+}
+
+func TestRemoveUserPublicKey(t *testing.T) {
+	t.Run("success", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
+		err = store.AddUserPublicKey(nil, "user1", publicKey)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		err = store.RemoveUserPublicKey(nil, "user1", publicKey)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// Verify key was removed
+		keys, err := store.GetUserPublicKeys(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(keys) != 0 {
+			t.Fatalf("expected 0 keys after removal, got %d", len(keys))
+		}
+
+		// Should be able to add the same key again after removal
+		err = store.AddUserPublicKey(nil, "user1", publicKey)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		// Verify key was re-added
+		keys, err = store.GetUserPublicKeys(nil, "user1")
+		if err != nil {
+			t.Fatal(err)
+		}
+		if len(keys) != 1 || keys[0] != publicKey {
+			t.Fatalf("expected 1 key after re-adding, got %d: %v", len(keys), keys)
+		}
+	})
+
+	t.Run("nonexistent_key", func(t *testing.T) {
+		store := createTestStore(t)
+		user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+		err := store.CreateUser(nil, user1)
+		if err != nil {
+			t.Fatal(err)
+		}
+
+		publicKey := "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ... user1@example.com"
+		// Try to remove a key that was never added
+		err = store.RemoveUserPublicKey(nil, "user1", publicKey)
+		// This should succeed (no error) even if the key doesn't exist
+		if err != nil {
+			t.Fatal(err)
+		}
+	})
+}
+
+func TestTransactionRollback(t *testing.T) {
+	store := createTestStore(t)
+	db := store.(*SQLiteStore).db
+
+	tx, err := db.Begin()
+	if err != nil {
+		t.Fatal(err)
+	}
+	defer tx.Rollback()
+
+	// Create a user within the transaction
+	user1 := User{Id: "user1", Username: "user1", Email: "user1@test.com"}
+	err = store.CreateUser(tx, user1)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	// Rollback the transaction
+	if err := tx.Rollback(); err != nil {
+		t.Fatal(err)
+	}
+
+	// User should not exist after rollback
+	_, err = store.GetUser(nil, "user1")
 	if err == nil {
-		t.Fatal("initialisation did not fail")
-	} else if err.Error() != "Store already initialised" {
-		t.Fatalf("Expected initialisation error, got: %s", err.Error())
+		t.Fatal("expected user to not exist after transaction rollback")
 	}
 }
 
-func TestGetAllTransitiveGroupsForGroup(t *testing.T) {
-	db, err := sql.Open("sqlite3", ":memory:")
-	if err != nil {
-		t.Fatal(err)
-	}
-	store, err := NewSQLiteStore(db)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = db.Exec(`
-        INSERT INTO groups (name, description)
-        VALUES
-            ('a', 'xxx'),
-            ('b', 'yyy');
-
-        INSERT INTO group_to_group (child_group, parent_group)
-        VALUES
-            ('a', 'b'),
-            ('b', 'a');
-        `)
-	if err != nil {
-		t.Fatal(err)
-	}
-	groups, err := store.GetAllTransitiveGroupsForGroup("a")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(groups) != 1 {
-		t.Fatalf("Expected exactly one transitive group, got: %s", groups)
-	}
-	expected := Group{"b", "yyy"}
-	if groups[0] != expected {
-		t.Fatalf("Expected %s, got: %s", expected, groups[0])
-	}
-}
-
-func TestGetAllTransitiveGroupsForUser(t *testing.T) {
-	db, err := sql.Open("sqlite3", ":memory:")
-	if err != nil {
-		t.Fatal(err)
-	}
-	store, err := NewSQLiteStore(db)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = db.Exec(`
-        INSERT INTO groups (name, description)
-        VALUES
-            ('a', 'xxx'),
-            ('b', 'yyy'),
-            ('c', 'zzz');
-
-        INSERT INTO group_to_group (child_group, parent_group)
-        VALUES
-            ('a', 'c'),
-            ('b', 'c');
-        INSERT INTO user_to_group (username, group_name)
-        VALUES
-            ('u', 'a'),
-            ('u', 'b');
-        `)
-	if err != nil {
-		t.Fatal(err)
-	}
-	groups, err := store.GetAllTransitiveGroupsForUser("u")
-	if err != nil {
-		t.Fatal(err)
-	}
-	if len(groups) != 3 {
-		t.Fatalf("Expected exactly one transitive group, got: %s", groups)
-	}
-}
-
-func TestParentAndChildGroupCases(t *testing.T) {
-	db, err := sql.Open("sqlite3", ":memory:")
-	if err != nil {
-		t.Fatal(err)
-	}
-	store, err := NewSQLiteStore(db)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = db.Exec(`
-	INSERT INTO groups (name, description)
-	VALUES
-		('a', 'xxx'),
-		('b', 'yyy');
-	`)
-	if err != nil {
-		t.Fatal(err)
-	}
-	err = store.AddChildGroup("a", "a")
-	if err == nil || err.Error() != "Parent and child groups can not have same name" {
-		t.Fatalf("Expected error, got: %v", err)
-	}
-	if err := store.AddChildGroup("a", "b"); err != nil {
-		t.Fatalf("Unexpected error: %v", err)
-	}
-}
-
-func TestRemoveChildGroupHandler(t *testing.T) {
-	db, err := sql.Open("sqlite3", ":memory:")
-	if err != nil {
-		t.Fatal(err)
-	}
-	store, err := NewSQLiteStore(db)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = db.Exec(`
-		CREATE TABLE IF NOT EXISTS groups (
-			name TEXT PRIMARY KEY,
-			description TEXT
-		);
-		INSERT INTO groups (name, description)
-        VALUES
-            ('bb', 'desc'),
-			('aa', 'desc');
-		CREATE TABLE IF NOT EXISTS owners (
-			username TEXT,
-			group_name TEXT,
-			FOREIGN KEY(group_name) REFERENCES groups(name),
-			UNIQUE (username, group_name)
-		);
-		INSERT INTO owners (username, group_name)
-        VALUES
-            ('testuser', 'bb');
-		CREATE TABLE IF NOT EXISTS group_to_group (
-			parent_group TEXT,
-			child_group TEXT
-		);
-        INSERT INTO group_to_group (parent_group, child_group)
-        VALUES
-            ('bb', 'aa');
-        `)
-	if err != nil {
-		t.Fatal(err)
-	}
-	server := &Server{
-		store:         store,
-		syncAddresses: make(map[string]struct{}),
-		mu:            sync.Mutex{},
-	}
-	router := mux.NewRouter()
-	router.HandleFunc("/group/{parent-group}/remove-child-group/{child-group}", server.removeChildGroupHandler).Methods(http.MethodPost)
-	req, err := http.NewRequest("POST", "/group/bb/remove-child-group/aa", nil)
-	req.Header.Set("X-Forwarded-User", "testuser")
-	if err != nil {
-		t.Fatal(err)
-	}
-	rr := httptest.NewRecorder()
-	router.ServeHTTP(rr, req)
-	if status := rr.Code; status != http.StatusSeeOther {
-		t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK)
-	}
-	if rr.Header().Get("Location") != "/group/bb" {
-		t.Errorf("handler returned wrong Location header: got %v want %v", rr.Header().Get("Location"), "/group/bb")
-	}
-}
-
-func TestFilterUsersByGroupHandler(t *testing.T) {
-	db, err := sql.Open("sqlite3", ":memory:")
-	if err != nil {
-		t.Fatal(err)
-	}
-	store, err := NewSQLiteStore(db)
-	if err != nil {
-		t.Fatal(err)
-	}
-	_, err = db.Exec(`
-		CREATE TABLE IF NOT EXISTS groups (
-			name TEXT PRIMARY KEY,
-			description TEXT
-		);
-		INSERT INTO groups (name, description)
-        VALUES
-            ('a', 'a'),
-			('b', 'b'),
-			('c', 'c'),
-			('d', 'd'),
-			('e', 'e'),
-			('f', 'f');
-		CREATE TABLE IF NOT EXISTS owners (
-			username TEXT,
-			group_name TEXT,
-			FOREIGN KEY(group_name) REFERENCES groups(name),
-			UNIQUE (username, group_name)
-		);
-		INSERT INTO owners (username, group_name)
-        VALUES
-            ('testuser1', 'a'),
-			('testuser2', 'd');
-		CREATE TABLE IF NOT EXISTS group_to_group (
-			parent_group TEXT,
-			child_group TEXT
-		);
-        INSERT INTO group_to_group (parent_group, child_group)
-        VALUES
-            ('a', 'b'),
-			('b', 'c'),
-			('d', 'e'),
-			('e', 'f');
-		CREATE TABLE IF NOT EXISTS user_to_group (
-			username TEXT,
-			group_name TEXT,
-			FOREIGN KEY(group_name) REFERENCES groups(name),
-			UNIQUE (username, group_name)
-		);
-        INSERT INTO user_to_group (username, group_name)
-        VALUES
-            ('u1', 'a'),
-			('u2', 'b'),
-			('u3', 'e'),
-			('u4', 'f'),
-			('u5', 'f'),
-			('u6', 'd'),
-			('u7', 'd');
-		CREATE TABLE IF NOT EXISTS users (
-			username TEXT PRIMARY KEY,
-			email TEXT,
-			UNIQUE (email)
-		);
-		INSERT INTO users (username, email)
-		VALUES
-			('u1','u1@d.d'),
-			('u2','u2@d.d'),
-			('u3','u3@d.d'),
-			('u4','u4@d.d'),
-			('u5','u5@d.d'),
-			('u6','u6@d.d'),
-			('u7','u7@d.d');
-		CREATE TABLE IF NOT EXISTS user_ssh_keys (
-			username TEXT,
-			ssh_key TEXT,
-			UNIQUE (ssh_key),
-			FOREIGN KEY(username) REFERENCES users(username)
-		);
-		INSERT INTO user_ssh_keys (username, ssh_key)
-		VALUES
-			('u1','ssh1'),
-			('u1','ssh1-1'),
-			('u2','ssh2'),
-			('u3','ssh3'),
-			('u4','ssh4'),
-			('u5','ssh5'),
-			('u6','ssh6'),
-			('u7','ssh7');
-        `)
-	if err != nil {
-		t.Fatal(err)
-	}
-	server := &Server{
-		store:         store,
-		syncAddresses: make(map[string]struct{}),
-		mu:            sync.Mutex{},
-	}
-	router := mux.NewRouter()
-	// case when group present or exist
-	router.HandleFunc("/api/users", server.apiGetAllUsers).Methods(http.MethodGet)
-	req, err := http.NewRequest("GET", "/api/users?groups=b,e,t", nil)
-	req.Header.Set("X-Forwarded-User", "testuser1")
-	if err != nil {
-		t.Fatal(err)
-	}
-	rr := httptest.NewRecorder()
-	router.ServeHTTP(rr, req)
-	expected := []User{
-		{"u1", "u1@d.d", []string{"ssh1", "ssh1-1"}},
-		{"u2", "u2@d.d", []string{"ssh2"}},
-		{"u3", "u3@d.d", []string{"ssh3"}},
-		{"u6", "u6@d.d", []string{"ssh6"}},
-		{"u7", "u7@d.d", []string{"ssh7"}},
-	}
-
-	var actual []User
-	err = json.NewDecoder(rr.Body).Decode(&actual)
-	if err != nil {
-		t.Fatal(err)
-	}
-	if !reflect.DeepEqual(actual, expected) {
-		t.Errorf("handler returned unexpected body: got %v want %v", actual, expected)
-	}
-
-	// case when no group present
-	req, err = http.NewRequest("GET", "/api/users?groups=", nil)
-	req.Header.Set("X-Forwarded-User", "testuser1")
-	if err != nil {
-		t.Fatal(err)
-	}
-	rr = httptest.NewRecorder()
-	router.ServeHTTP(rr, req)
-
-	expected = []User{
-		{"u1", "u1@d.d", []string{"ssh1", "ssh1-1"}},
-		{"u2", "u2@d.d", []string{"ssh2"}},
-		{"u3", "u3@d.d", []string{"ssh3"}},
-		{"u4", "u4@d.d", []string{"ssh4"}},
-		{"u5", "u5@d.d", []string{"ssh5"}},
-		{"u6", "u6@d.d", []string{"ssh6"}},
-		{"u7", "u7@d.d", []string{"ssh7"}},
-	}
-	err = json.NewDecoder(rr.Body).Decode(&actual)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if !reflect.DeepEqual(actual, expected) {
-		t.Errorf("handler returned unexpected body: got %v want %v", actual, expected)
-	}
-
-	// case when wrong groups
-	req, err = http.NewRequest("GET", "/api/users?groups=x,y", nil)
-	req.Header.Set("X-Forwarded-User", "testuser1")
-	if err != nil {
-		t.Fatal(err)
-	}
-	rr = httptest.NewRecorder()
-	router.ServeHTTP(rr, req)
-
-	expected = []User{}
-	err = json.NewDecoder(rr.Body).Decode(&actual)
-	if err != nil {
-		t.Fatal(err)
-	}
-
-	if !reflect.DeepEqual(actual, expected) {
-		t.Errorf("handler returned unexpected body: got %v want %v", actual, expected)
-	}
+func TestConcurrentAccess(t *testing.T) {
+	// Skip this test as SQLite in-memory databases don't handle true concurrency well
+	// This test would be more appropriate for integration testing with a real database
+	t.Skip("Skipping concurrent access test for in-memory SQLite database")
 }
diff --git a/core/auth/proxy/main.go b/core/auth/proxy/main.go
index f8ab620..a4a2efc 100644
--- a/core/auth/proxy/main.go
+++ b/core/auth/proxy/main.go
@@ -35,6 +35,7 @@
 var f embed.FS
 
 var noAuthPathRegexps []*regexp.Regexp
+var allowedGroups []Group
 
 func initPathPatterns() error {
 	for _, p := range strings.Split(*noAuthPathPatterns, ",") {
@@ -51,6 +52,38 @@
 	return nil
 }
 
+type getGroupReq struct {
+	GroupId string `json:"groupId"`
+}
+
+type getGroupResp struct {
+	Self Group `json:"self"`
+}
+
+func initAllowedGroups() error {
+	for _, groupId := range strings.Split(*groups, ",") {
+		gid := strings.TrimSpace(groupId)
+		if len(gid) == 0 {
+			continue
+		}
+		var buf bytes.Buffer
+		if err := json.NewEncoder(&buf).Encode(getGroupReq{gid}); err != nil {
+			return err
+		}
+		resp, err := http.Post(fmt.Sprintf("%s/api/get-group", *membershipAddr), "application/json", &buf)
+		if err != nil {
+			return err
+		}
+		var info getGroupResp
+		if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
+			return err
+		}
+		fmt.Println(info.Self)
+		allowedGroups = append(allowedGroups, info.Self)
+	}
+	return nil
+}
+
 type cachingHandler struct {
 	h http.Handler
 }
@@ -91,7 +124,7 @@
 
 type UnauthorizedPageData struct {
 	MembershipPublicAddr string
-	Groups               []string
+	Groups               []Group
 }
 
 func renderUnauthorizedPage(w http.ResponseWriter, groups []string) {
@@ -102,7 +135,7 @@
 	}
 	data := UnauthorizedPageData{
 		MembershipPublicAddr: *membershipPublicAddr,
-		Groups:               groups,
+		Groups:               allowedGroups,
 	}
 	w.Header().Set("Content-Type", "text/html")
 	w.WriteHeader(http.StatusUnauthorized)
@@ -141,13 +174,13 @@
 		}
 		if *groups != "" {
 			hasPermission := false
-			tg, err := getTransitiveGroups(user.Identity.Traits.Username)
+			tg, err := getGroupsUserCanActAs(user.Identity.Id)
 			if err != nil {
 				http.Error(w, err.Error(), http.StatusInternalServerError)
 				return
 			}
-			for _, i := range strings.Split(*groups, ",") {
-				if slices.Contains(tg, strings.TrimSpace(i)) {
+			for _, i := range allowedGroups {
+				if slices.Contains(tg, i) {
 					hasPermission = true
 					break
 				}
@@ -219,44 +252,35 @@
 	if err != nil {
 		return nil, err
 	}
-	data := make(map[string]any)
-	if err := json.NewDecoder(resp.Body).Decode(&data); err != nil {
-		return nil, err
-	}
-	// TODO(gio): remove debugging
-	b, err := json.MarshalIndent(data, "", "  ")
-	if err != nil {
-		return nil, err
-	}
-	fmt.Println(string(b))
-	var buf bytes.Buffer
-	if err := json.NewEncoder(&buf).Encode(data); err != nil {
-		return nil, err
-	}
-	tmp := buf.String()
 	if resp.StatusCode == http.StatusOK {
 		u := &user{}
-		if err := json.NewDecoder(strings.NewReader(tmp)).Decode(u); err != nil {
+		if err := json.NewDecoder(resp.Body).Decode(u); err != nil {
 			return nil, err
 		}
 		return u, nil
 	}
 	e := &authError{}
-	if err := json.NewDecoder(strings.NewReader(tmp)).Decode(e); err != nil {
+	if err := json.NewDecoder(resp.Body).Decode(e); err != nil {
 		return nil, err
 	}
 	if e.Error.Status == "Unauthorized" {
 		return nil, nil
 	}
-	return nil, fmt.Errorf("Unknown error: %s", tmp)
+	return nil, fmt.Errorf("Unknown error")
+}
+
+type Group struct {
+	Id          string `json:"id"`
+	Title       string `json:"title"`
+	Description string `json:"description"`
 }
 
 type MembershipInfo struct {
-	MemberOf []string `json:"memberOf"`
+	CanActAs []Group `json:"canActAs"`
 }
 
-func getTransitiveGroups(user string) ([]string, error) {
-	resp, err := http.Get(fmt.Sprintf("%s/%s", *membershipAddr, user))
+func getGroupsUserCanActAs(user string) ([]Group, error) {
+	resp, err := http.Get(fmt.Sprintf("%s/api/user/%s", *membershipAddr, user))
 	if err != nil {
 		return nil, err
 	}
@@ -264,7 +288,7 @@
 	if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
 		return nil, err
 	}
-	return info.MemberOf, nil
+	return info.CanActAs, nil
 }
 
 func main() {
@@ -275,6 +299,9 @@
 	if err := initPathPatterns(); err != nil {
 		log.Fatal(err)
 	}
+	if err := initAllowedGroups(); err != nil {
+		log.Fatal(err)
+	}
 	http.Handle("/.auth/static/", http.StripPrefix("/.auth", cachingHandler{http.FileServer(http.FS(f))}))
 	http.HandleFunc("/", handle)
 	fmt.Printf("Starting HTTP server on port: %d\n", *port)
diff --git a/core/auth/proxy/unauthorized.html b/core/auth/proxy/unauthorized.html
index 130cf81..28c8913 100644
--- a/core/auth/proxy/unauthorized.html
+++ b/core/auth/proxy/unauthorized.html
@@ -15,7 +15,7 @@
             <p>
                 Only members of
                 {{ range $index, $group := .Groups }}
-                <a href="{{ $.MembershipPublicAddr }}/group/{{ $group }}">{{ $group }}</a>{{ if not (IsLast $index $.Groups) }},{{ end }}
+                <a href="{{ $.MembershipPublicAddr }}/group/{{ $group.Id }}">{{ $group.Title }}</a>{{ if not (IsLast $index $.Groups) }},{{ end }}
                 {{ end }}
                 are authorized to access this page.
             </p>
diff --git a/core/auth/ui/api.go b/core/auth/ui/api.go
index b8c5bad..cced90d 100644
--- a/core/auth/ui/api.go
+++ b/core/auth/ui/api.go
@@ -129,6 +129,10 @@
 	}
 }
 
+type identityCreateResp struct {
+	Id string `json:"id"`
+}
+
 func (s *APIServer) identityCreate(w http.ResponseWriter, r *http.Request) {
 	var req identityCreateReq
 	if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
@@ -157,16 +161,26 @@
 		http.Error(w, "failed", http.StatusInternalServerError)
 		return
 	}
-	if resp.StatusCode != http.StatusCreated {
-		var e ErrorResponse
-		if err := json.NewDecoder(resp.Body).Decode(&e); err != nil {
+	if resp.StatusCode == http.StatusCreated {
+		var idResp identityCreateResp
+		if err := json.NewDecoder(resp.Body).Decode(&idResp); err != nil {
 			http.Error(w, "failed to decode", http.StatusInternalServerError)
 			return
 		}
-		errorMessages := extractKratosErrorMessage(e)
-		replyWithErrors(w, errorMessages)
+		if err := json.NewEncoder(w).Encode(idResp); err != nil {
+			http.Error(w, "failed to decode", http.StatusInternalServerError)
+			return
+		}
 		return
 	}
+	var e ErrorResponse
+	if err := json.NewDecoder(resp.Body).Decode(&e); err != nil {
+		http.Error(w, "failed to decode", http.StatusInternalServerError)
+		return
+	}
+	errorMessages := extractKratosErrorMessage(e)
+	replyWithErrors(w, errorMessages)
+	return
 }
 
 type changePasswordReq struct {
diff --git a/core/installer/app_configs/app_global_env.cue b/core/installer/app_configs/app_global_env.cue
index 6b0c1ec..0bd3c8f 100644
--- a/core/installer/app_configs/app_global_env.cue
+++ b/core/installer/app_configs/app_global_env.cue
@@ -124,7 +124,7 @@
 					upstream:       "\(service.name).\(release.namespace).svc.cluster.local:\(service.port)"
 					whoAmIAddr:     "https://accounts.\(g.domain)/sessions/whoami"
 					loginAddr:      "https://accounts-ui.\(g.domain)/login"
-					membershipAddr: "http://memberships-api.\(g.namespacePrefix)core-auth-memberships.svc.cluster.local/api/user"
+					membershipAddr: "http://memberships-api.\(g.namespacePrefix)core-auth-memberships.svc.cluster.local"
 					if g.privateDomain == "" {
 						membershipPublicAddr: "https://memberships.\(g.domain)"
 					}
diff --git a/core/installer/server/welcome/server.go b/core/installer/server/welcome/server.go
index 198f637..23f9e00 100644
--- a/core/installer/server/welcome/server.go
+++ b/core/installer/server/welcome/server.go
@@ -177,12 +177,17 @@
 	}
 }
 
+type identityCreateResp struct {
+	Id string `json:"id"`
+}
+
 func (s *Server) createAccount(w http.ResponseWriter, r *http.Request) {
 	req, err := extractReq(r)
 	if err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
+	var idResp identityCreateResp
 	{
 		var buf bytes.Buffer
 		cr := apiCreateAccountReq{req.Username, req.Password}
@@ -223,8 +228,12 @@
 			})
 			return
 		}
+		if err := json.NewDecoder(resp.Body).Decode(&idResp); err != nil {
+			http.Error(w, "Error Decoding JSON", http.StatusInternalServerError)
+			return
+		}
 	}
-	if err := s.createUser(req.Username); err != nil {
+	if err := s.createUser(idResp.Id, req.Username); err != nil {
 		http.Error(w, err.Error(), http.StatusInternalServerError)
 		return
 	}
@@ -232,23 +241,29 @@
 }
 
 type firstAccount struct {
-	Created bool     `json:"created"`
-	Domain  string   `json:"domain"`
-	Groups  []string `json:"groups"`
+	Created bool    `json:"created"`
+	Domain  string  `json:"domain"`
+	Groups  []group `json:"groups"`
+}
+
+type user struct {
+	Id       string `json:"id"`
+	Username string `json:"username"`
+	Email    string `json:"email"`
+}
+
+type group struct {
+	Id          string `json:"id"`
+	Title       string `json:"title"`
+	Description string `json:"description"`
 }
 
 type initRequest struct {
-	User   string   `json:"user"`
-	Email  string   `json:"email"`
-	Groups []string `json:"groups"`
+	User   user    `json:"user"`
+	Groups []group `json:"groups"`
 }
 
-type createUserRequest struct {
-	User  string `json:"user"`
-	Email string `json:"email"`
-}
-
-func (s *Server) createUser(username string) error {
+func (s *Server) createUser(id, username string) error {
 	_, err := s.repo.Do(func(r soft.RepoFS) (string, error) {
 		var fa firstAccount
 		if err := soft.ReadYaml(r, "first-account.yaml", &fa); err != nil {
@@ -256,10 +271,14 @@
 		}
 		var resp *http.Response
 		var err error
+		u := user{
+			id,
+			username,
+			fmt.Sprintf("%s@%s", username, fa.Domain),
+		}
 		if fa.Created {
-			req := createUserRequest{username, fmt.Sprintf("%s@%s", username, fa.Domain)}
 			var buf bytes.Buffer
-			if err := json.NewEncoder(&buf).Encode(req); err != nil {
+			if err := json.NewEncoder(&buf).Encode(u); err != nil {
 				return "", err
 			}
 			resp, err = http.Post(
@@ -268,7 +287,10 @@
 				&buf,
 			)
 		} else {
-			req := initRequest{username, fmt.Sprintf("%s@%s", username, fa.Domain), fa.Groups}
+			req := initRequest{
+				u,
+				fa.Groups,
+			}
 			var buf bytes.Buffer
 			if err := json.NewEncoder(&buf).Encode(req); err != nil {
 				return "", err
diff --git a/core/installer/tasks/infra.go b/core/installer/tasks/infra.go
index d69ba3a..907bba0 100644
--- a/core/installer/tasks/infra.go
+++ b/core/installer/tasks/infra.go
@@ -10,7 +10,19 @@
 	"github.com/giolekva/pcloud/core/installer/soft"
 )
 
-var initGroups = []string{"admin"}
+type group struct {
+	Id          string `json:"id"`
+	Title       string `json:"title"`
+	Description string `json:"description"`
+}
+
+var initGroups = []group{
+	group{
+		"admin",
+		"Admin",
+		"Administrators",
+	},
+}
 
 func CreateRepoClient(env installer.EnvConfig, st *state) Task {
 	t := newLeafTask("Create repo client", func() error {
@@ -77,9 +89,9 @@
 }
 
 type firstAccount struct {
-	Created bool     `json:"created"`
-	Domain  string   `json:"domain"`
-	Groups  []string `json:"groups"`
+	Created bool    `json:"created"`
+	Domain  string  `json:"domain"`
+	Groups  []group `json:"groups"`
 }
 
 func ConfigureFirstAccount(env installer.EnvConfig, st *state) Task {
@@ -407,11 +419,15 @@
 		if env.PrivateDomain != "" {
 			network = "Private"
 		}
+		var initGroupIds []string
+		for _, g := range initGroups {
+			initGroupIds = append(initGroupIds, g.Id)
+		}
 		if _, err := st.appManager.Install(app, instanceId, appDir, namespace, map[string]any{
 			"network":       network,
 			"repoAddr":      st.ssClient.GetRepoAddress("config"),
 			"sshPrivateKey": string(keys.RawPrivateKey()),
-			"authGroups":    strings.Join(initGroups, ","),
+			"authGroups":    strings.Join(initGroupIds, ","),
 		}); err != nil {
 			return err
 		}
