# Cybus::User

The **Cybus::User** resource allows you to create new users and optionally assign them initial permissions.

Permissions can be granted in the following ways:

* **Role-based access control**: Assign users to [roles](#roles). This is recommended for maintainability, especially in complex setups.
* **Direct permission assignment**: List [permissions](#permissions) directly for the user. This is less maintainable and should be avoided for complex setups.

The [resource identifier](https://docs.cybus.io/2-0-6/documentation/services/service-commissioning-files/resources/..#resource-id) automatically becomes the username for new users.

## Username Requirements

Follow these requirements when setting up usernames:

* **Minimum length**: Three characters
* **Allowed characters**: Usernames may contain:
  * ASCII letters (both lowercase and uppercase)
  * Numbers
  * Underscore (`_`)
  * Period (`.`)
* **Pattern**: Must follow the regular expression pattern: `[a-zA-Z0-9][a-zA-Z0-9_.]*`
* **Restrictions**: Hyphens (`-`) are not permitted in usernames as they serve as special separators between service IDs and usernames in Connectware's Docker container resource management.

The actual username in the system will be prefixed with the individual [service ID](https://docs.cybus.io/2-0-6/documentation/services/serviceid) (e.g., `ServiceID.myUser`).

## User Properties

| Property                    | Type       | Required     |
| --------------------------- | ---------- | ------------ |
| [password](#password)       | `string`   | **Required** |
| [permissions](#permissions) | `object[]` | Optional     |
| [roles](#roles)             | `string[]` | Optional     |

### password

* **Required**
* Type: `string`
* Minimum length: 5 characters

### permissions

This is the list of permissions for this user. We recommend not using this property directly. Instead, define [Cybus::Role](https://docs.cybus.io/2-0-6/documentation/services/service-commissioning-files/resources/cybus-role) resources with the list of actual permissions, and add those roles to the [roles](#roles) property.

* **Optional**
* Type: `object[]`; all items must be of the type: `object` with the following properties:

| Property                | Type   | Required     |
| ----------------------- | ------ | ------------ |
| [context](#context)     | string | **Required** |
| [operation](#operation) | string | **Required** |
| [resource](#resource)   | string | **Required** |

#### context

This is the context in which the user permissions for the resource should be interpreted.

* **Required**
* Type: `enum`; the value of this property **must** be one of the following:
  * `mqtt`: When describing permissions for MQTT topics.
  * `http`: When describing permissions for REST API paths.

#### operation

The allowed access operation to the resource.

* **Required**
* Type: `enum`; the value of this property **must** be one of the following:
  * `read`
  * `write`
  * `readWrite`

#### resource

This is the resource path. It can be a RESTful API path or an MQTT topic.

* **Required**
* Type: `string`

### roles

This is the list of [Cybus::Role](https://docs.cybus.io/2-0-6/documentation/services/service-commissioning-files/resources/cybus-role) identifiers for this user that describe the actual permissions. This is the recommended way of specifying permissions.

* **Optional**
* Type: `string[]`
* All items must be of type: `string`.
* When referencing roles, you must use the `!ref` operator to create proper references.

## Cybus::User Examples

### User with Direct Permissions

{% code lineNumbers="true" %}

```yaml
myUser:
  type: Cybus::User
  properties:
    password: 'somePassword1'
    permissions:
      - resource: userspace/werner/#
        operation: readWrite
        context: mqtt
```

{% endcode %}

### User with Role Assignments (Recommended)

{% code lineNumbers="true" %}

```yaml
# First define a role
operatorRole:
  type: Cybus::Role
  properties:
    permissions:
      - resource: userspace/data/#
        operation: read
        context: mqtt
      - resource: userspace/controls/#
        operation: readWrite
        context: mqtt

# Then assign the role to a user with !ref
productionUser:
  type: Cybus::User
  properties:
    password: 'securePassword123'
    roles:
      - !ref operatorRole
```

{% endcode %}
