Administration Guide

Complete guide for administering the Riptide Application Manager.

Table of Contents

Accessing the Admin Interface

The Application Manager provides a full web-based administration interface. Admins reach it at the customer's admin hostname over HTTPS — Riptide-hosted environments use https://boathouse.riptide.solutions (staging) and https://dock.riptide.solutions (production); customer deployments use whatever hostname their reverse proxy serves AM under.

Endpoint URL on the host Purpose
Web UI http://localhost:11401 Reverse proxy hits this; admins reach it through the customer's admin hostname
API http://localhost:11402 Service-to-service traffic; rarely hit directly
Health probe http://localhost:11402/health Container readiness — used by deploy scripts and operator checks
Swagger http://localhost:11402/swagger Available when Api:Swagger:Enabled=true (default off in Production)

localhost:NNN here means "from a shell on the deployment host itself" — never a user-facing URL. End users always go through the reverse proxy.

First Login

On first startup, the entrypoint creates a default admin user (idempotent — safe to re-run):

Username: admin
Password: Admin@2026!

Change this password immediately after first login. See the Deployment Guide for the full first-startup walk-through.

Admin Interface Overview

The web UI provides the following modules (accessible from the navigation bar — labels collapse to icon-only on viewports narrower than 1920px):

Module URL Path Purpose
Dashboard / Administration / Overview metrics, active sessions, recent activity
Applications /applications Register and manage SDK applications
Bundles /bundles Application bundles for grouped trial registration
Users /users Manage administrator-provisioned users
Trials /trial-users Manage trial user accounts and team members
Roles /roles Define roles and assign capabilities
Sessions /sessions View and terminate active sessions
Configuration /configuration File management with Monaco editor
Audit Logs /audit-logs View audit trail
Identity /identity-providers Configure external OIDC / SAML identity providers
Capabilities /security/dashboard Capability declaration inventory (SecurityAdmin only)
Tenants /tenants Multi-tenant management
Health /applications/health Monitor application health checks
Cloud /cloud-bindings Per-application cross-account assumption metadata for cloud-posture probes
Licenses /license-keys Riptide Platform license key management
Documentation /docs In-app docs portal (opens in new tab)
Link SSO /auth/link-sso Link your account to an SSO provider
Exit Admin (logout) End admin session

Authentication Flows

Login

Navigate to the customer admin hostname's /auth/login. Enter your admin username and password. Sessions use sliding expiration — default 60 minutes of inactivity before automatic logout (configurable via Authentication:SessionIdleTimeoutMinutes).

Change password

Available at /auth/change-password or via the user menu. Requires the current password. The system enforces password history — recently-used passwords cannot be reused (the count is configurable via Security:PasswordHistory:Count).

Forgot password

When an email provider is configured, the forgot-password flow at /auth/forgot-password sends a time-limited reset token to the user's email address. Tokens expire after a configurable period (default 60 minutes).

SSO / OIDC login

When external identity providers are configured and enabled, the login page shows additional "Sign in with [Provider]" buttons alongside the password form. Clicking an SSO option redirects to the external provider (e.g., Entra ID, Okta) and returns the user to AM after authentication. Just-in-time provisioning can create the local user on first SSO login if configured per provider.

Existing local-password admins can link their account to an SSO provider via Link SSO in the navbar. After linking, the admin can log in with either the password or the SSO provider for that identity.

Daily Operations

Health Monitoring

Check system health via the API:

curl http://localhost:11402/health

Or use the Application Health module in the web UI to monitor registered applications.

Service Management

# Check service status
docker compose ps

# View logs
docker compose logs -f

# Restart services
docker compose restart

# Stop services
docker compose down

# Start services
docker compose up -d

Log Management

# View last 100 lines
docker compose logs --tail=100

# View logs for specific timeframe
docker compose logs --since 2h

# Save logs to file
docker compose logs > logs/docker-$(date +%Y%m%d-%H%M%S).log

Background jobs

The Hangfire dashboard at /hangfire shows scheduled and recurring background work — security audits, trial cleanup, email queue, etc. Access requires admin authentication. Use it to verify a job ran, retry a failed job, or pause a recurring job temporarily.

User Management

Application Users (Admin-Provisioned)

Use the Admin Users module (/admin-users) to:

  • Create new users with email, name, and role assignments
  • View user details including login history, roles, and application access
  • Activate/Deactivate user accounts
  • Unlock accounts locked by failed login attempts (5 attempts triggers a 15-minute lockout)
  • Reset passwords — generates a reset token and sends an email
  • Grant/revoke application access

Trial Users (Self-Service)

Use the Trials module (/trial-users) to manage self-registered trial accounts:

  • View all trial registrations with status, verification state, and trial dates
  • Search and filter by active/inactive status, email, name
  • Edit user details, extend trial duration
  • View Details — full user profile, activity history, associated applications
  • Extend Trial — add days to a user's trial without editing the full profile
  • Activate/Deactivate trial accounts
  • View trial application assignments

Self-registration flow

Trial users self-register through the public registration page at /trial/register (anonymous, no admin login required). The flow:

  1. User fills out the registration form (name, email, application choice).
  2. AM sends a verification email through the configured email provider.
  3. User clicks the verification link, which marks the account verified and starts the trial period.
  4. Trial becomes active for the configured duration (default 7 days; configurable per-bundle).

If the deployment uses the trials hostname split (e.g. https://trials.example.com/trial/register), the bare / on that hostname redirects to /trial/register — see the Deployment Guide for the reverse-proxy and Web:PublicHosts configuration.

Email verification

The email verification page at /email-verification allows users to check their verification status and request a resend if the original link was lost. Rate limiting prevents abuse (default 3 resends per hour, configurable via Trial:EmailVerification:ResendRateLimit).

Bulk Operations

Use Import/Export (/import-export) for:

  • CSV Import — bulk create trial users from a CSV file
  • CSV Export — export user data for reporting

Use Advanced Search (/advanced-search) for:

  • Cross-entity search across admin users and trial users
  • Filter by name, email, status, role, verification state
  • Export search results to CSV

Role & Capability Management

Roles

Use the Roles module (/roles) to define roles that group capabilities:

  • Create roles with a name, description, and sort order
  • Assign capabilities to roles — determines what permissions role members have
  • Set population method — whether the role is manually assigned or auto-assigned to new users
  • Delete roles (with confirmation)

Capabilities

Use the Capabilities module (/capabilities) to define granular permissions:

  • Capabilities follow the pattern resource:action (e.g., permits:create, reports:view)
  • Capabilities are organized by category for easier management
  • Assign capabilities to roles, not directly to users

Authorization Flow

  1. Administrator creates capabilities representing application permissions
  2. Administrator creates roles that group related capabilities
  3. Administrator assigns roles to users
  4. SDK applications check capabilities via [RequireCapability("resource:action")]

Application Management

Use the Applications module (/applications) to register and manage SDK-consuming applications:

  • Register new applications with name, description, and launch URL
  • View application details, access grants, and health status
  • Activate/Deactivate applications
  • Manage API credentials for SDK communication (key generation and rotation)
  • Grant/Revoke user access to specific applications

Identity Provider Management

Use the Identity Providers module (/identity-providers) to configure external identity providers for SSO:

  • Add OIDC providers (Entra ID, Okta, Keycloak, etc.) with authority URL, client ID/secret, and scopes
  • Configure claim mappings — map IdP claims to Application Manager user fields
  • Enable/Disable providers — controls whether they appear on the login page
  • Configure JIT provisioning — automatically create users on first SSO login
  • Set default tenant and roles for newly provisioned SSO users

The login page dynamically shows "Sign in with [Provider]" buttons for all enabled identity providers alongside the standard password login form.

Configuration Management

Use the Configuration module (/configuration) to manage application configuration files:

  • Hierarchical file/folder tree — Unix-inspired structure per application
  • Monaco editor — in-browser code editing with syntax highlighting
  • Version history — every edit creates a new version
  • Rollback — restore any previous version
  • SDK applications fetch configuration via the REST API

Session Management

Use the Sessions module (/sessions) to monitor and manage active user sessions:

  • View all active sessions with user, IP address, creation time, and expiry
  • Filter by user or active-only
  • Terminate individual sessions (with confirmation)
  • Sessions expire automatically based on configured idle and absolute timeouts

License Key Management

Use the Licenses module (/license-keys) to manage Riptide Platform license keys — the signed tokens that control which applications and features your installation is licensed to use.

Import a license key

  1. Click Import License on the license list page (or navigate to /license-keys/import).
  2. Paste the full license token into the License Token textarea. Tokens start with RIPTIDE-PLATFORM-v2- and contain a base64-encoded payload and signature separated by a colon.
  3. Optionally add Notes (customer name, purchase order number, contract reference, etc.).
  4. The Activate this license now checkbox is on by default. Activating writes the license to /platform/license.json in the configuration tree and deactivates whichever license was previously active — only one license is active at a time.
  5. Click Import License to save.

Duplicate token imports are rejected. A token already past its expiry date is stored with status "Expired" and is not activated regardless of the checkbox.

License list and details

The list at /license-keys shows every imported key newest-first. Each row displays IssuedTo (with an "Active License" badge if it's currently active), Installation ID, expiry (or "Never" for perpetual), status (Active / Revoked / Expired), licensed-application count, and import date. The action menu offers View Details and (for active/non-revoked rows) Revoke.

The detail page at /license-keys/{id} shows:

  • License Information — IssuedTo, Installation ID, masked token (first 30 + last 10 chars), issued + expiry dates, status.
  • Licensed Applications & Features — tree view of every licensed application with its enabled/disabled status and nested features.
  • Import & Revocation Details — who imported it and when; revocation details if applicable.
  • Notes — anything captured on import.

Validate a license

From the detail page, Validate decodes the payload, verifies the RSA-SHA256 signature against the configured public key (Riptide:Platform:License:PublicKey, when set), and checks expiry. The result alert shows valid/invalid status, signature-verification result, and days remaining.

Revoke a license

From the list (action menu) or the detail page, Revoke permanently changes status to Revoked. If the revoked license was active, no license is active until another is imported or activated. Revocation cannot be undone.

Audit & Activity Logs

Use the Audit Logs module (/audit-logs) to review the audit trail:

  • All significant actions are logged: logins, user changes, role assignments, configuration edits
  • Filter by entity type, action, user, and date range
  • Supports compliance and incident investigation

Database Administration

Database Locations

Two SQLite databases store all data:

data/identity/identity.db          — Users, sessions, roles, capabilities, trials
data/configuration/configuration.db — Applications, file nodes, versions, admin users

Database Statistics

# Identity database size and table counts
sqlite3 data/identity/identity.db "
SELECT
    (SELECT COUNT(*) FROM Users) as Users,
    (SELECT COUNT(*) FROM Sessions) as Sessions,
    (SELECT COUNT(*) FROM Roles) as Roles,
    (SELECT COUNT(*) FROM ActivityLogs) as ActivityLogs;
"

# Configuration database stats
sqlite3 data/configuration/configuration.db "
SELECT
    (SELECT COUNT(*) FROM ManagedApplications) as Applications,
    (SELECT COUNT(*) FROM FileNodes) as FileNodes,
    (SELECT COUNT(*) FROM FileVersions) as Versions;
"

Database Optimization

# Vacuum databases (reclaim space)
sqlite3 data/identity/identity.db "VACUUM;"
sqlite3 data/configuration/configuration.db "VACUUM;"

# Analyze for query optimization
sqlite3 data/identity/identity.db "ANALYZE;"
sqlite3 data/configuration/configuration.db "ANALYZE;"

# Check integrity
sqlite3 data/identity/identity.db "PRAGMA integrity_check;"
sqlite3 data/configuration/configuration.db "PRAGMA integrity_check;"

Migration Management

Migrations run automatically on startup. To check current version:

sqlite3 data/identity/identity.db "
SELECT MigrationId FROM __EFMigrationsHistory ORDER BY MigrationId;
"

Backup & Recovery

Manual Backup

mkdir -p backups/$(date +%Y%m%d)

# Backup databases
cp data/identity/identity.db backups/$(date +%Y%m%d)/identity.db
cp data/configuration/configuration.db backups/$(date +%Y%m%d)/configuration.db

# Backup configuration
cp .env backups/$(date +%Y%m%d)/.env

Automated Backup Script

#!/bin/bash
# backup.sh — Run via cron: 0 2 * * * /path/to/backup.sh

BACKUP_DIR="/var/backups/riptide-app-manager"
DATE=$(date +%Y%m%d-%H%M%S)
RETENTION_DAYS=30

mkdir -p "$BACKUP_DIR"

# Use SQLite's backup command (safer than cp for active databases)
docker exec riptide-application-manager \
    sqlite3 /app/data/identity/identity.db ".backup '/tmp/identity-backup.db'"
docker cp riptide-application-manager:/tmp/identity-backup.db \
    "$BACKUP_DIR/identity-$DATE.db"

docker exec riptide-application-manager \
    sqlite3 /app/data/configuration/configuration.db ".backup '/tmp/config-backup.db'"
docker cp riptide-application-manager:/tmp/config-backup.db \
    "$BACKUP_DIR/config-$DATE.db"

# Cleanup old backups
find "$BACKUP_DIR" -name "*.db" -mtime +$RETENTION_DAYS -delete

Restore from Backup

# Stop services
docker compose down

# Restore databases
cp backups/identity-YYYYMMDD.db data/identity/identity.db
cp backups/config-YYYYMMDD.db data/configuration/configuration.db

# Verify integrity
sqlite3 data/identity/identity.db "PRAGMA integrity_check;"
sqlite3 data/configuration/configuration.db "PRAGMA integrity_check;"

# Start services
docker compose up -d

Security Management

Password Policy

Password policies are configured in appsettings.json under the Security section:

  • Minimum length, complexity requirements (uppercase, lowercase, digit, special character)
  • Password history depth (prevents reuse)
  • Account lockout: 5 failed attempts triggers a 15-minute lockout

Session Security

  • Cookie-based authentication with HttpOnly, Secure flags
  • 8-hour sliding expiration with configurable absolute timeout
  • Sessions can be terminated individually from the admin UI

API Security

  • All API endpoints require X-Api-Key header authentication
  • API keys are hashed and validated using the Riptide SDK ApiKeyAuthenticationHandler
  • API keys are managed through the Applications module (issue, revoke, scope)

OIDC Security

  • Client secrets should be managed via environment variables, not stored in source
  • JIT provisioning can be restricted by allowed email domains
  • Each provider can be enabled/disabled independently

Capability Declaration Inventory Administration

The Application Manager integrates with SDK 1.3.0 security packages to record and report on the SDK security capabilities each application self-declares. The inventory maps those declarations to SOC 2, HIPAA, FedRAMP, and StateRAMP framework templates. This is not a security audit: no probing, configuration inspection, or external evidence collection is performed today. See Security & Compliance for details on what the scores mean and what they do not.

SecurityAdmin Role

Only users with the SecurityAdmin role claim can:

  • View the Capabilities nav item in the top navigation
  • Access /security/dashboard (application × framework declaration coverage matrix)
  • Access /security/report/{applicationId} (per-application control report + coverage trend)
  • Trigger on-demand declaration re-evaluation via POST /security/audit/{applicationId}

To grant the SecurityAdmin role to a user, use the Roles administration UI, or directly in the database:

-- Find or create the SecurityAdmin role
INSERT OR IGNORE INTO Roles (Id, Name, Description, CreatedDate)
VALUES (lower(hex(randomblob(16))), 'SecurityAdmin', 'Access to capability declaration inventory features', datetime('now'));

-- Assign to a user (replace email and role ID accordingly)
INSERT INTO UserRoles (Id, UserId, RoleId, AssignedDate)
VALUES (
    lower(hex(randomblob(16))),
    (SELECT Id FROM TrialUsers WHERE Email = 'admin@example.com'),
    (SELECT Id FROM Roles WHERE Name = 'SecurityAdmin'),
    datetime('now')
);

Running On-Demand Audits

Audits can be triggered from two places:

  1. Security Dashboard — click "Run Audit" next to any application, then select a framework.
  2. Application Details page — the Security Posture card (visible to SecurityAdmin) has a "Run Audit" form.
  3. APIPOST /security/audit/{applicationId} with ?framework=SOC2 (or HIPAA, FedRAMP, StateRAMP).

Enabling Scheduled Audits

Scheduled audits are disabled by default. To enable them, set the following in appsettings.json:

{
  "SecurityAudit": {
    "ScheduledAudit": {
      "Enabled": true,
      "IntervalHours": 24,
      "Frameworks": ["SOC2", "HIPAA", "FedRAMP", "StateRAMP"]
    }
  }
}

When enabled, SecurityAuditBackgroundService runs automatically at the configured interval, auditing all active applications against each configured framework and storing results in ApplicationSecurityAssessments.

Score Thresholds

Score Badge Color Meaning
≥ 80 Green (success) Compliant / passing
50–79 Yellow (warning) Partial compliance — attention needed
< 50 Red (danger) Non-compliant — action required

Custom Compliance Templates

Admins can add custom compliance templates without restarting the application:

  1. In the Configuration module, navigate to the application-manager ManagedApplication.
  2. Create the directory /security/ if it does not exist.
  3. Upload or edit /security/compliance-templates.json with your custom framework definitions.

ComplianceTemplateLoader.EnsureLoadedAsync() is called before each audit run, so templates take effect immediately.

Querying Assessment History

-- View latest assessment per application and framework
SELECT 
    ApplicationId,
    Framework,
    Score,
    Source,
    AssessedAt
FROM ApplicationSecurityAssessments
WHERE (ApplicationId, Framework, AssessedAt) IN (
    SELECT ApplicationId, Framework, MAX(AssessedAt)
    FROM ApplicationSecurityAssessments
    GROUP BY ApplicationId, Framework
)
ORDER BY Score ASC;

-- Score trend for a specific application + framework
SELECT Score, Source, TriggeredBy, AssessedAt
FROM ApplicationSecurityAssessments
WHERE ApplicationId = 'your-app-id'
  AND Framework = 'SOC2'
ORDER BY AssessedAt DESC
LIMIT 20;

Troubleshooting

Cannot Login

  1. Check if the admin user exists and is active in the web UI
  2. Verify the account is not locked out (check via Sessions module)
  3. Check logs: docker compose logs -f
  4. If locked out, wait 15 minutes or unlock via the Admin Users module

High CPU Usage

docker stats riptide-application-manager

Consider running database optimization (VACUUM + ANALYZE).

Database Locked

# Restart services to release locks
docker compose restart

Disk Space Issues

# Check database sizes
du -h data/identity/identity.db data/configuration/configuration.db

# Vacuum to reclaim space
sqlite3 data/identity/identity.db "VACUUM;"
sqlite3 data/configuration/configuration.db "VACUUM;"

Getting Help


Last Updated: March 4, 2026