General administration

This guide covers the general administration of the application (the core engine).


Table of contents

  1. Admin dashboard
  2. User management
  3. Role system
  4. Authentication methods
  5. Application settings
  6. Module system
  7. Backup and restore
  8. Logging and debug
  9. Security

Core engine

1. Admin dashboard

Reached through the user menu > Administration (only visible with the app_admin role).

admin

The administration panel is organised into sections in the left-hand sidebar:

graph TD
 A[Administration] --> B[Dashboard]
 A --> C[Users]
 A --> D[Settings]
 A --> E[Maintenance]
 A --> F[Modules]
 C --> C1[User list]
 C --> C2[Create a user]
 D --> D1[Appearance]
 D --> D2[Debug / Trace]
 D --> D3[Authentication methods]
 D --> D4[SMTP]
 E --> E1[Backup and restore]
 E --> E2[Update]
 F --> F1[Module management]

2. User management

Access: app_admin only.

User list

users

A table of all accounts with:

  • Username, e-mail
  • Authentication method (local / LDAP / OAuth)
  • Assigned roles
  • Status (active / inactive)
  • Last login
  • Actions: edit, delete

Creating a user

creUser

FieldRequiredNotes
UsernameYesUnique, cannot be changed after creation
E-mailNo
PasswordYes (on creation)Min. 8 characters, hashed with bcrypt
Auth methodYeslocal, ldap or oauth
RolesNoCheckboxes grouped by module
LanguageNoInherits the default if empty
ThemeNoInherits the default if empty
ActiveYesAn inactive account cannot log in

Editing a user

Same form as creation, with the following rules:

  • The username is read-only
  • The password is optional (empty = keep the existing one)
  • Protection: you cannot remove your own app_admin role nor delete your own account

Accounts created automatically (LDAP/OAuth)

On a first LDAP or OAuth login, an account is created automatically with no role. The administrator must assign the roles manually.


3. Role system

Multi-role architecture

Each user can have 0 to N roles. Roles are of two kinds:

graph LR
 subgraph "System roles"
 A[app_admin<br>Super-administrator]
 end
 subgraph "Module roles"
 B[oracle_admin]
 C[oracle_user]
 D[module_admin]
 E[module_user]
 end
 A -.->|"implicit access<br>to everything"| B
 A -.-> C
 A -.-> D
 A -.-> E

app_admin is an implicit super-role: every role check (hasRole, hasAnyRole, canAccess, canAccessAsAdmin) returns true if the user holds it.

Roles declared by modules

Each module declares its own roles in its descriptor. Convention:

  • <module>_admin: full access to the module (configuration + consultation)
  • <module>_user: consultation only

Roles are automatically synchronised into the roles table when the application starts (idempotent).

Checking roles in code

MethodUsage
$auth->hasRole('oracle_admin')Checks a specific role
$auth->hasAnyRole('oracle_admin', 'oracle_user')Checks for at least one role
$auth->requireRole('oracle_admin')Blocks with HTTP 403 if the role is missing

4. Authentication methods

Overview

Methods are configured under Settings > Authentication methods.

authMethods

Each method can be enabled/disabled independently. Several methods can coexist.

Local authentication

No configuration required. Accounts and passwords are stored in the application’s SQLite database. Passwords are hashed with bcrypt.

LDAP authentication

ParameterDescription
HostLDAP server address (e.g. ldap.example.com)
PortPort (389 for LDAP, 636 for LDAPS)
Base DNSearch root (e.g. dc=example,dc=com)
Bind DNService account DN (e.g. cn=admin,dc=...)
Bind PasswordService account password (encrypted at rest)
User DN PatternSearch pattern (e.g. uid={user},{base_dn})
TLS insecureAccept self-signed certificates

Variables available in the User DN Pattern:

VariableReplaced by
{user}The username entered
{base_dn}The value of the Base DN field
{domain}The domain extracted from the DC= of the Base DN

A Test connection button validates the configuration.

settings

OAuth / OIDC authentication

ParameterDescription
Client IDThe application’s identifier with the provider
Client SecretClient secret (encrypted at rest)
Redirect URICallback URL (e.g. https://app.example.com/login.php)
Auth URLThe provider’s authorization URL
Token URLToken exchange URL

Compatible with any OpenID Connect provider (Keycloak, Azure AD, Google, etc.).


5. Application settings

Appearance

ParameterDescription
Default themeTheme applied to new users and to visitors
Default languageLanguage applied when the user has no preference

apparence

SMTP (sending e-mails)

ParameterDescription
SMTP serverHost name
Port25, 465 (SSL) or 587 (STARTTLS)
EncryptionNone, TLS (STARTTLS) or SSL. Self-signed certificates are accepted (internal relays).
SMTP authenticationCheckbox. Uncheck for an anonymous internal relay (no credentials required).
UsernameActive only if the checkbox is ticked
PasswordEncrypted at rest. Active only if the checkbox is ticked
Sender addressThe From: address
Sender nameDisplay name

The Send a test button sends a real HTML e-mail (with the application logo) to the address entered. The full SMTP conversation log (commands and responses) is shown to make diagnosis easier.

SMTP


6. Module system

Principle

Each module is a folder under mon-appli/modules/<name>/ containing a module.php descriptor. Discovery is automatic at startup.

sequenceDiagram
 participant B as Bootstrap
 participant M as Module Registry
 participant DB as SQLite database
 B->>M: glob(modules/*/module.php)
 loop Each module
 M->>DB: INSERT OR IGNORE module
 M->>DB: INSERT OR IGNORE module roles
 end
 Note over M: Modules discovered but not necessarily active

Enable / Disable

modules

On the Module management page, each module is shown as a card with:

  • Name, version, description, icon
  • Green badge (active) or red badge (inactive)
  • Declared roles
  • Dependencies
  • Enable/Disable button

Dependency rules:

  • A module can only be enabled if all the modules it depends on (depends_on) are already active
  • A module can only be disabled if no active module depends on it

Activation hook: some modules run a verification script before activation (e.g. checking that a prerequisite configuration is in place). On failure, activation is refused with an error message and a redirect to the module’s configuration page.

Grouped activation (PostgreSQL): if the postgresql module is inactive, an “Enable PostgreSQL and its dependencies” button appears in the page header. It enables the postgresql module together with all the modules it depends on (depends_on, followed transitively), in the order imposed by the dependencies. Each module’s activation hooks and provisioning run normally; if a module fails, the other activations continue and a message summarises the enabled modules and the failures (with their reason). Unlike single activation, there is no redirect to the configuration page of the failed module.

Adding and updating a module

At the bottom of the Module management page, the “Add or update a module” form accepts a ZIP archive containing a single module folder, with its module.php at the root of that folder (the format produced by *Developer -> Export a module*). The folder name and the descriptor’s name key must match, otherwise the archive is refused.

Processing depends on whether the module exists:

CaseBehaviour
Module absentAdded disabled. Enable it afterwards.
Module already installedUpdated in place, without disabling it first.

On an update, only the module’s files are replaced. Kept unchanged: its active/inactive state, its roles and their assignments to users, its configuration and its data tables. This is the key difference with deletion, which erases roles, assignments and configuration.

Update flow:

  1. the application enters maintenance mode (app_admin users keep access);
  2. the installed version is backed up to securite/backups/module_<name>_<timestamp>.zip — the 3 most recent backups are kept;
  3. the files are replaced; on failure, the previous version is restored automatically;
  4. if the module is active and declares an activation hook, it is replayed (the hook point for a new version’s schema migrations); its failure is reported without disabling the module;
  5. maintenance mode is lifted.
The backup produced is itself a valid module archive: to roll back to the previous version, simply re-upload it through this same form.

If the replacement fails and the restore also fails, maintenance mode is deliberately left active: restore the backup named in the error message, then lift maintenance from *Administration -> Update*.

Deleting a module

Reserved for disabled modules. It removes the module folder then cleans the database: the modules row, the module’s roles (and therefore their user assignments, cascading) and the configuration file. The module’s data tables are not deleted. To ship a new version of a module, use the update, not the delete + reinstall pair.

Module configuration

Each module can store its configuration in a JSON file securite/modules/<name>.json (formerly the modules.config field, migrated automatically at startup). Access is through:

$moduleRegistry->getConfig('oracle') // read
$moduleRegistry->updateConfig('oracle', [...]) // write

7. Backup and restore

Access: app_admin only.

backups

Scope

The backup covers the whole securite/ directory:

ContentFile
Application databasedatabase.sqlite
Encryption keymaster.key
Oracle walletswallets/
CPU schedule snapshotscpu_schedule_snapshots/
Other secret filesEvery file under securite/
Important: the master.key key and the database.sqlite database must be backed up together. Losing the key makes the encrypted passwords unrecoverable.

Create a backup

Two options:

ActionResult
Back up locallyCreates metadata_YYYYMMDD_HHMMSS.zip in securite/backups/
DownloadGenerates the ZIP and offers it for download

Restore a backup

  1. From a file: upload a ZIP file through the form
  2. From a local backup: select it in the list

The restore:

  • Automatically creates a pre-restore backup (pre_restore_YYYYMMDD_HHMMSS.zip) before overwriting the files
  • Extracts file by file with a success/failure report
  • Restores the permissions of master.key (mode 0600)
Warning: the restore replaces the database. After a restore, accounts, roles and configuration revert to the state of the backup.

Managing local backups

The table lists the ZIPs in securite/backups/ with:

  • File name, size, date
  • Buttons: Restore, Delete

8. Logging and debug

Log files

FileContentActive by default
log/app.logApplication events (logins, errors)Yes
log/debug.logDetailed debug messagesNo
log/trace.logFull trace of every HTTP requestNo

Enabling

Under Settings > Debug / Trace:

ParameterDescription
Debug modeEnables debug.log — detailed messages
Trace modeEnables trace.log — every HTTP request with URL, parameters, headers

debug

Performance: trace mode generates a large volume of logs. Only enable it temporarily to diagnose a problem.

9. Security

Encryption at rest

Secrets (LDAP, OAuth, Oracle passwords, CMDB wallet) are encrypted with libsodium (XSalsa20-Poly1305 AEAD).

graph LR
 A[Plaintext<br>password] -->|Crypto::encrypt| B["enc_v1:base64(nonce||ciphertext)"]
 B -->|Crypto::decrypt| C[Plaintext<br>password]
 D[securite/master.key<br>32 bytes] --> A
 D --> B
  • Master key: securite/master.key (32 bytes, auto-generated, mode 0600)
  • Format: enc_v1: prefix followed by the nonce and ciphertext in base64
  • Idempotence: Crypto::encrypt() does not re-encrypt an already encrypted value; an empty string stays empty

CSRF protection

Every POST form includes a CSRF token (csrf_token) checked server-side via hash_equals().

Session protection

MeasureDetail
HttpOnly cookieJavaScript cannot read the session cookie
SameSite=Lax cookieProtection against cross-site CSRF attacks
Secure cookieSent over HTTPS only (where applicable)
RegenerationThe session ID is regenerated every 5 minutes
Lifetime1 hour (configurable via SESSION_LIFETIME)

Prepared statements

Every SQL query goes through bound parameters. No concatenation of user data into queries.


Appendices

Tree of important files

securite/
 database.sqlite Application database (SQLite)
 master.key Encryption key (mode 0600)
 backups/ ZIP backups
 wallets/<id>/ Oracle Cloud wallets
 cpu_schedule_snapshots/ CPU schedule snapshots
 remediation_oracle.json Scheduled remediation tasks
 cmdb.sqlite Local CMDB cache

log/
 app.log Application log
 debug.log Debug (if enabled)
 trace.log HTTP trace (if enabled)

mon-appli/
 bootstrap.php Common entry point
 login.php Authentication
 index.php Dashboard
 admin/ Administration pages
 modules/oracle/ Oracle module
 i18n/ Translation files
 assets/ CSS, JS, images
 includes/ Header, footer, navigation

Database schema (main tables)

erDiagram
 users ||--o{ user_roles : "has"
 roles ||--o{ user_roles : "assigned to"
 users {
 int id PK
 text username UK
 text email
 text password_hash
 text auth_method
 text language
 text theme
 int active
 datetime last_login
 }
 roles {
 int id PK
 text name UK
 text label
 text module
 int is_system
 }
 user_roles {
 int user_id FK
 int role_id FK
 datetime granted_at
 }
 auth_config {
 text method PK
 int enabled
 text config
 }
 settings {
 text key PK
 text value
 }
 modules {
 text name PK
 text label
 int active
 text config
 }