Skip to main content

Write Access Control

In this tutorial, we will modify the schema in the first schema tutorial to add write access control rules.

Out of the box, Kwil supports a variety of access control capabilities. If you wish to implement more advances access control logic than what is natively available, you can do so by adding an Extension to your network.

Raising Errors

In an action, you can use SQL CASE statements to raise errors if certain conditions are not met. If an error is raised, the transaction will fail entirely, and data will not be written to the network.

social_media.kf
// private action to check if user exists
action check_user() private view {
SELECT
CASE
WHEN NOT EXISTS (SELECT 1 FROM users WHERE address=@caller) THEN ERROR('User does not exist')
ELSE null
END as user_status;
}

Action Privacy

Action privacy enforces whether an action can be called by a user or not. Public actions can be called by users. Private actions can only be called by other actions.

The distinction between public and private actions are similar to the distinction between public and private methods in object-oriented programming, where public methods are accessible from outside the class, and private methods are only accessible from within the class.

social_media.kf
// private action to check if user exists
action check_user() private view {
SELECT
CASE
WHEN NOT EXISTS (SELECT 1 FROM users WHERE address=@caller) THEN ERROR('User does not exist')
ELSE null
END as user_status;
}

// before creating a post, check if the user exists
action create_post ($id, $title, $content, $date_string) public {
check_user();
INSERT INTO posts (id, title, content, author_id, post_date)
VALUES (
$id,
$title,
$content,
(SELECT id FROM users WHERE address=@caller),
$date_string
);
}

Owner-only Actions

Actions can be given an owner privacy level, which means that only the owner of the database can call the action. This is useful for actions that should only be called by the database owner, such as admin operations.

social_media.kf
// owner only action to delete a user
action delete_user($user_id) public owner {
DELETE FROM users WHERE id = $user_id;
}