User Guide

Everything you need to install, configure, and build with Montycat — from getting started to governance, advanced operations, and security.

Montycat has a two-tier user system to manage security and access control:

Superowner

The Superowner acts as the top-level administrator.

Responsibilities

  • Create and manage stores and keyspaces.
  • Assign permissions (READ, WRITE, ALL) to Owners.

Only one Superowner can exist per Montycat instance.

Owner

  • Owners are users responsible for managing stores and keyspaces within their assigned scope.
  • Permissions are restricted by default and must be explicitly granted by the superowner.

Owners cannot create other owners or assign permissions beyond their granted scope.

You can create a superowner using CLI.
Only one Superowner per Montycat instance is allowed.
Attempting to create another will fail.

montycat create-superowner --username <superowner name> --password <superowner password>

or

montycat console
> create-superowner username <superowner name> password <superowner password>

exit

An Owner is created by the Superowner.
They can manage specific stores and keyspaces:

montycat console
> create-owner username <owner name> password <owner password>

exit
from montycat import Engine

connection = Engine(
    host="<host>",
    port=<port>,
    username="<superowner username>",
    password="<superowner password>",
)

res = await connection.create_owner(owner="<owner username>", password="<owner password>")

Owners can be removed only by the superowner:

montycat console
> remove-owner username <owner name>

exit
from montycat import Engine

connection = Engine(
    host="<host>",
    port=<port>,
    username="<superowner username>",
    password="<superowner password>",
)

res = await connection.remove_owner(owner="<owner username>")

Owners are restricted by default.
Permissions (READ, WRITE, ALL) can be granted per store or keyspace.

Note: If a keyspace exists both in-memory and persistent, granting permission affects both instances.

montycat console
> grant-to owner <owner name> permission all store <store name>

exit
montycat console
> grant-to owner <owner name> permission all store <store name> keyspaces <keyspace1 name> <keyspace2 name>

exit

If you use clients make sure you specified a store property.

Note: Clients API does not support granting permissions at keyspace level, only at store level.
Valid permissions: read, write, all

from montycat import Engine, Permission

connection = Engine(
    host="<host>",
    port=<port>,
    username="<superowner username>",
    password="<superowner password>",
    store="<store name>"
)

res = await connection.grant_to(owner="<owner name>", permission=Permission.ALL, keyspaces=["Employees"])
# 'Permission' can be ALL, READ, WRITE
# 'keyspaces' arg is optional

Permissions can be revoked at store or keyspace level.
As with granting, if a keyspace exists in both in-memory and persistent storage, revoking affects both.

montycat console
> revoke_from owner <owner name> permission all store <store name>

exit
montycat console
> revoke_from owner <owner name> permission all store <store name> keyspaces <keyspace1 name> <keyspace2 name>

exit

If you use clients make sure you specified a store property.

from montycat import Engine, Permission

connection = Engine(
    host="<host>",
    port=<port>,
    username="<superowner username>",
    password="<superowner password>",
    store="<store name>"
)

# 'Permission' can be ALL, READ, WRITE
# 'keyspaces' arg is optional

res = await connection.revoke_from(owner="<owner name>", permission=Permission.ALL, keyspaces=["Employees"])

You can list all current owners and their access levels:

montycat console
> list-owners

exit
from montycat import Engine

connection = Engine(
    host="<host>",
    port=<port>,
    username="<superowner username>",
    password="<superowner password>",
)

res = await connection.list_owners()

# {"status": True, "payload": {"Owner1": {"read": [...], "write": [...], "all": []}}, "error": None}