Skip to main content

Framework to allow untrusted users to perform privileged system tasks.

Project description

A Python framework to allow untrusted users to perform privileged system tasks.

Overview

Regent comes in two parts:

  • a service which runs as the privileged system user, defines a set of operations it will perform, and listens for requests on a linux socket file

  • a client library to ask the service to perform the operations

A service is intended for use with clients on a single host. Alternatively its socket can be mounted within a docker container to control its host or other containers.

The authentication system is designed on the assumption that the unprivileged user is untrusted and can be compromised. For non-harmful operations a basic shared key will deter casual attackers, and for more high-risk commands it supports out-of-channel activation, to allow two-factor authentication or administrator approval.

Example

A service which defines a system command (whoami) and returns its output:

import subprocess

from regent.service import Operation, Service


class WhoAmI(Operation):
    def perform(self):
        value = subprocess.check_output("whoami")
        value = value.strip()
        return value


service = Service(
    socket_path="/tmp/regent-whoami.sock",
    socket_secret="123456",
)
service.register("whoami", WhoAmI)
service.listen()

A client which calls the service:

from regent.client import Client

client = Client(
    socket_path="/tmp/regent-whoami.sock",
    socket_secret="123456",
)

response = client.request("whoami")
print(response["data"])

More complicated examples can be found in the examples dir, including:

  • make changes to the firewall

  • restart the server

Implementation

Testing your service manually

Regent uses human-readable JSON, terminated in a newline. Using socat:

socat - UNIX-CONNECT:/tmp/my-regent.sock

send the following, ending in a UNIX-style newline (\n):

{“secret”: “123456”, “op”: “my-op”}

and you’ll receive your response:

{"error": "something failed"}

Internal messaging API

This is the raw API between the client and service. Knowledge of this will not be required in normal Regent use if you’re using a client.

A connection to the service API should send a JSON object with the following key/values:

secret Socket secret op Operation name data Optional: Data for the operation

The service will return either:

error Error message

or

success True uid Unique ID for this operation request, or null if complete data Data from the operation or pending async auth

JSON objects should be terminated with a newline.

If the original operation requires an asynchronous authentication step, the client should send the following JSON object:

secret Socket secret uid UID for a stored operation request (passed from async auth) data Data for authenticating the auth request

Changelog

0.1.0 - 2022-11-19

  • First release of Python version rewritten from original Perl

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

regent-0.1.0.tar.gz (10.2 kB view hashes)

Uploaded Source

Built Distribution

regent-0.1.0-py3-none-any.whl (10.9 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page