FeaturesUse CasesBlogAPI ReferenceWhy CorePlexMLPricing
Start Free
← Back to Blog
Enterprise13 min read

Enterprise Security: RBAC, SSO, and Multi-Tenancy in CorePlexML

CorePlexML Team·

Why Enterprise Security Matters for ML

Machine learning platforms occupy a unique position in the enterprise security landscape. They handle some of the most sensitive assets an organization possesses: proprietary training data that may contain customer PII, model intellectual property that represents months of R&D investment, and prediction pipelines that directly influence business decisions. A breach or misconfiguration in an ML platform can expose customer data, leak competitive advantages, or allow unauthorized users to manipulate predictions that drive revenue-critical systems.

Yet many ML platforms treat security as an afterthought. They start as internal tools with minimal access controls, and by the time the organization grows to require proper governance, the platform's architecture makes retrofitting security difficult. CorePlexML takes the opposite approach: security is built into the foundation, not bolted on after the fact.

This guide covers the full security architecture of CorePlexML, from multi-tenancy and role-based access control to SSO integration, row-level security, API key management, and audit logging.

Multi-Tenancy Architecture

CorePlexML implements multi-tenancy at the project level. Every resource in the platform (datasets, experiments, models, deployments, alerts, retraining policies) belongs to a project, and projects belong to users. This creates a natural isolation boundary: a user can only access resources within their own projects unless explicit sharing is configured.

Project-level isolation extends to the database layer. Every query that retrieves resources includes a project ownership check, ensuring that even if a bug exists in the application logic, the database will not return resources from another user's project.

from coreplexml import CorePlexClient

client = CorePlexClient(
    base_url="https://api.coreplexml.io",
    api_key="your-api-key"
)

# Create a project with team access
project = client.projects.create(
    name="Fraud Detection Pipeline",
    description="Real-time fraud scoring for payment processing",
    team_members=[
        {"email": "alice@company.com", "role": "editor"},
        {"email": "bob@company.com", "role": "viewer"},
        {"email": "carol@company.com", "role": "editor"}
    ]
)

print(f"Project ID: {project.id}")
print(f"Owner: {project.owner}")
print(f"Team size: {len(project.team_members)}")

Resource boundaries are enforced at every API endpoint. When a user requests a dataset, the system verifies not just that the dataset exists, but that the requesting user has the appropriate role in the project that owns the dataset. This ownership verification is implemented as a middleware layer that runs before any business logic, making it impossible to bypass through application-level bugs.

Role-Based Access Control

CorePlexML implements three roles with clearly defined permission boundaries. Each role represents a different level of trust and capability within a project.

Owner

The owner role has full control over the project and all its resources. Owners can create, read, update, and delete any resource. They can manage team membership, including inviting new members, changing roles, and removing access. They can configure billing, change project settings, and delete the project entirely. Every project has exactly one owner, which is the user who created it. Ownership can be transferred but not shared.

Editor

The editor role can create and modify resources within the project but cannot manage team membership or project settings. Editors can upload datasets, run experiments, create deployments, configure alerts, and set up retraining policies. They can modify resources created by other editors. They cannot invite new team members, change roles, or delete the project.

Viewer

The viewer role has read-only access to all resources within the project. Viewers can browse datasets, review experiment results, inspect model metrics, and view deployment status. They cannot create, modify, or delete any resource. The viewer role is appropriate for stakeholders who need visibility into ML operations without the ability to make changes, such as product managers, compliance officers, or executive sponsors.

# Manage team roles
client.projects.update_member(
    project_id="proj_abc123",
    email="bob@company.com",
    role="editor"
)

# List current team with roles
team = client.projects.list_members(project_id="proj_abc123")
for member in team:
    print(f"{member.email}: {member.role} "
          f"(joined: {member.joined_at.strftime('%Y-%m-%d')})")

The permission matrix covers every resource type in the platform:

  • Datasets: Owners and editors can upload, modify, and delete. Viewers can read and download.
  • Experiments: Owners and editors can create and configure. Viewers can view results and leaderboards.
  • Models: Owners and editors can register, transition stages, and update model cards. Viewers can view metrics and lineage.
  • Deployments: Owners and editors can create, modify strategies, and trigger rollbacks. Viewers can view status and metrics.
  • Alerts: Owners and editors can create and configure rules and channels. Viewers can view alert history.
  • Retraining policies: Owners and editors can create and modify. Viewers can view policy configuration and execution history.

Authentication Stack

CorePlexML supports multiple authentication methods to accommodate different access patterns and enterprise requirements.

Cookie-Based Sessions for UI

The web interface uses HTTP-only, secure, same-site cookies for session management. When a user logs in through the browser, the server creates a session, stores it in PostgreSQL, and sets a session cookie. Subsequent requests include this cookie automatically, and the server validates it against the stored session data.

Sessions have configurable expiration. By default, sessions expire after 24 hours of inactivity or 7 days of total lifetime, whichever comes first. Organizations can adjust these values to match their security policies. When a session expires, the user is redirected to the login page.

CSRF protection is enforced for all state-modifying requests. The server generates a CSRF token that must be included in POST, PUT, and DELETE requests. The frontend includes this token automatically through the ApiClient library.

Bearer Token Authentication for API

Programmatic access uses bearer tokens in the Authorization header. Tokens are generated through the API key management interface and can be scoped to specific permissions and projects:

# Authenticate with bearer token
import requests

headers = {
    "Authorization": "Bearer cpx_live_abc123def456",
    "Content-Type": "application/json"
}

response = requests.get(
    "https://api.coreplexml.io/api/projects",
    headers=headers
)

Bearer tokens do not expire automatically but can be revoked at any time through the management interface. Organizations that require token rotation can set expiration dates at creation time.

API Key Management

API keys provide scoped, auditable access for automated systems, CI/CD pipelines, and third-party integrations. Each key has a name, a set of permissions, an optional expiration date, and an optional project scope:

# Create a scoped API key
api_key = client.api_keys.create(
    name="CI/CD Pipeline - Production",
    permissions=["deployments:read", "deployments:create",
                 "models:read", "predictions:create"],
    project_ids=["proj_abc123"],
    expires_at="2026-06-30T23:59:59Z",
    description="Used by GitHub Actions for automated model deployment"
)

print(f"Key ID: {api_key.id}")
print(f"Key: {api_key.key}")  # Only shown once at creation time
print(f"Permissions: {api_key.permissions}")
print(f"Expires: {api_key.expires_at}")

# List active API keys
keys = client.api_keys.list()
for key in keys:
    print(f"{key.name}: {key.id} - "
          f"Last used: {key.last_used_at or 'Never'} - "
          f"Expires: {key.expires_at or 'Never'}")

# Revoke a compromised key
client.api_keys.revoke(key_id="key_compromised_123")

The key value is displayed only once at creation time and is never stored in plain text. If a key is lost, a new one must be created and the old one revoked. This prevents key exfiltration from database backups or internal access.

API key usage is tracked and available in the audit log. Each API call records which key was used, when, from what IP address, and what action was performed. This provides a complete activity trail for any automated system.

SSO and SAML Integration

Enterprise organizations typically manage identity through a central provider such as Okta, Azure Active Directory, or Google Workspace. CorePlexML integrates with these providers through SAML 2.0 and OIDC protocols, allowing users to authenticate with their existing corporate credentials.

SAML Configuration

SAML integration requires configuring CorePlexML as a service provider (SP) in your identity provider (IdP). The platform provides the SP metadata (entity ID, ACS URL, and certificate) that your IdP needs:

# Configure SAML for your organization
saml_config = client.auth.configure_saml(
    organization_id="org_enterprise_01",
    config={
        "idp_entity_id": "https://idp.company.com/saml/metadata",
        "idp_sso_url": "https://idp.company.com/saml/sso",
        "idp_certificate": "-----BEGIN CERTIFICATE-----\nMIIC...\n-----END CERTIFICATE-----",
        "sp_entity_id": "https://api.coreplexml.io/saml/metadata",
        "attribute_mapping": {
            "email": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress",
            "first_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname",
            "last_name": "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname",
            "groups": "http://schemas.xmlsoap.org/claims/Group"
        },
        "auto_provision_users": True,
        "default_role": "viewer",
        "group_role_mapping": {
            "ml-admins": "owner",
            "ml-engineers": "editor",
            "ml-stakeholders": "viewer"
        }
    }
)

The group_role_mapping parameter maps IdP groups to CorePlexML roles. When a user authenticates through SAML, the platform reads their group memberships from the SAML assertion and assigns the corresponding role. This allows organizations to manage ML platform access through their existing group management workflows.

The auto_provision_users flag controls whether new users are created automatically when they authenticate for the first time through SSO. When enabled, a user who exists in the IdP but not in CorePlexML will be created with the default_role. When disabled, users must be explicitly invited before they can log in.

OAuth Providers

For organizations that prefer OAuth-based authentication, CorePlexML supports Google and GitHub as identity providers:

# Configure Google OAuth
oauth_config = client.auth.configure_oauth(
    provider="google",
    config={
        "client_id": "your-google-client-id.apps.googleusercontent.com",
        "client_secret": "your-google-client-secret",
        "allowed_domains": ["company.com", "subsidiary.com"],
        "auto_provision_users": True
    }
)

# Configure GitHub OAuth
github_config = client.auth.configure_oauth(
    provider="github",
    config={
        "client_id": "your-github-client-id",
        "client_secret": "your-github-client-secret",
        "allowed_organizations": ["company-org"],
        "auto_provision_users": True
    }
)

The allowed_domains and allowed_organizations parameters restrict authentication to users who belong to approved domains or organizations. Without these restrictions, any user with a Google or GitHub account could authenticate, which is inappropriate for enterprise deployments.

PostgreSQL Row-Level Security

CorePlexML leverages PostgreSQL's Row-Level Security (RLS) as a defense-in-depth mechanism for data isolation. RLS policies are defined at the database level and are enforced by PostgreSQL itself, independent of the application code.

When RLS is enabled on a table, every query is automatically filtered to return only rows that the current user is authorized to access. Even if the application constructs a query without a proper WHERE clause (due to a bug or injection attack), RLS ensures that unauthorized rows are invisible.

The RLS policies in CorePlexML are structured around project ownership. Each table that contains project-scoped data has a policy that restricts access to rows where the project_id matches one of the user's authorized projects. This creates a database-level isolation boundary that complements the application-level ownership checks.

RLS provides protection against several attack vectors that application-level checks alone cannot fully address. SQL injection attacks that bypass application logic are still constrained by RLS policies. Internal tools or admin scripts that accidentally omit ownership filters cannot access unauthorized data. Database backup and recovery operations that restore data to the wrong environment are protected by RLS enforcement on the restored data.

Audit Logging

CorePlexML maintains a comprehensive audit log that records every significant event in the platform. The audit log is append-only and immutable: events cannot be modified or deleted after they are recorded.

# Query the audit log
events = client.audit.list_events(
    project_id="proj_abc123",
    event_types=["deployment.created", "deployment.rollback",
                 "model.stage_transition", "api_key.created"],
    start_time="2026-02-01T00:00:00Z",
    end_time="2026-03-01T00:00:00Z",
    limit=50
)

for event in events:
    print(f"[{event.timestamp}] {event.event_type}")
    print(f"  User: {event.user_email}")
    print(f"  IP: {event.ip_address}")
    print(f"  Details: {event.details}")
    print()

The audit log captures the following categories of events:

  • Authentication events: Login attempts (successful and failed), session creation and expiration, SSO assertions, API key usage
  • Authorization events: Permission checks, role changes, project membership changes
  • Resource lifecycle events: Creation, modification, and deletion of datasets, experiments, models, deployments, alerts, and retraining policies
  • Deployment events: Deployment creation, canary advancement, rollback, promotion, and decommission
  • Security events: API key creation and revocation, password changes, SSO configuration changes, failed authorization attempts

Each event record includes the timestamp, the user who initiated the action (or the API key that was used), the IP address of the request, the resource affected, and a structured details object with event-specific information.

GDPR Compliance

For organizations subject to the General Data Protection Regulation, CorePlexML provides tools to fulfill the key rights defined by the regulation:

Right to access. Users can export all data associated with their account, including datasets, model metadata, prediction logs, and audit events. The export is generated as a structured archive that includes both the data and the metadata describing its format.

Right to erasure. Users can request deletion of their account and all associated data. The deletion process removes user records, project data, model artifacts, and prediction logs. Audit log entries are anonymized rather than deleted, preserving the audit trail while removing personally identifiable information.

Right to data portability. All data exports use open, standard formats (CSV for tabular data, JSON for metadata, ONNX for model artifacts where supported) to ensure portability to other platforms.

# Export all user data (GDPR data access request)
export = client.compliance.export_user_data(
    user_id="user_abc123",
    format="archive",
    include_predictions=True,
    include_audit_events=True
)

print(f"Export ID: {export.id}")
print(f"Status: {export.status}")
print(f"Estimated size: {export.estimated_size_mb} MB")
print(f"Download URL: {export.download_url}")
print(f"Expires: {export.expires_at}")

Session Management

CorePlexML provides fine-grained control over session lifecycle to support enterprise security policies:

# Configure session policies for an organization
client.auth.configure_session_policy(
    organization_id="org_enterprise_01",
    config={
        "max_idle_minutes": 30,
        "max_lifetime_hours": 8,
        "max_concurrent_sessions": 3,
        "enforce_single_device": False,
        "require_re_auth_for_sensitive_ops": True,
        "sensitive_operations": [
            "deployment.create",
            "api_key.create",
            "project.delete",
            "model.stage_transition"
        ]
    }
)

# View active sessions for a user
sessions = client.auth.list_sessions(user_email="alice@company.com")
for session in sessions:
    print(f"Session: {session.id}")
    print(f"  Created: {session.created_at}")
    print(f"  Last active: {session.last_active_at}")
    print(f"  IP: {session.ip_address}")
    print(f"  Device: {session.user_agent}")
    print()

# Revoke a specific session
client.auth.revoke_session(session_id="sess_abc123")

# Revoke all sessions for a user (force logout everywhere)
client.auth.revoke_all_sessions(user_email="alice@company.com")

The max_concurrent_sessions limit prevents credential sharing by restricting the number of active sessions a single user can have. When the limit is exceeded, the oldest session is automatically revoked.

The require_re_auth_for_sensitive_ops setting forces users to re-authenticate (enter their password or complete SSO) before performing high-impact operations. This protects against session hijacking by ensuring that a stolen session cookie cannot be used to create deployments, generate API keys, or delete projects without re-verifying the user's identity.

Best Practices for Enterprise Deployment

Enforce SSO for all users. Disable password-based authentication once SSO is configured. SSO provides centralized credential management, multi-factor authentication through the IdP, and automatic deprovisioning when employees leave the organization.

Use the principle of least privilege. Start new team members with the viewer role and escalate to editor only when they need write access. Most stakeholders who interact with the ML platform only need to view dashboards and results, not modify resources.

Rotate API keys regularly. Set expiration dates on all API keys and establish a rotation schedule. Quarterly rotation is a reasonable default for most organizations. CI/CD pipeline keys should be rotated whenever pipeline configurations change.

Review audit logs periodically. Schedule monthly reviews of the audit log, focusing on failed authentication attempts, permission changes, and unusual patterns like API key usage from unexpected IP addresses.

Scope API keys narrowly. Create separate API keys for different systems and restrict each key to the minimum permissions it needs. A CI/CD pipeline that only deploys models should not have permission to delete datasets. A monitoring system that reads metrics should not have permission to create deployments.

Enable RLS and verify isolation. After configuring multi-tenancy, verify that RLS policies are working correctly by attempting cross-project access with different user accounts. This verification should be part of your regular security testing procedures.

Enterprise security for ML platforms is not a single feature but a layered architecture. Each layer, from RBAC to RLS to audit logging, addresses a different class of risk. Together, they provide the defense-in-depth that enterprise organizations require to trust an ML platform with their most sensitive data and most critical predictions.

For more details on CorePlexML's security architecture and compliance certifications, visit the security page.