Metadata-Version: 2.2
Name: gl-iam-binary
Version: 0.3.9b1
Summary: A pluggable Identity and Access Management (IAM) SDK for GDP Labs applications.
Author-email: Sandy Dewangga <sandy.dewangga@gdplabs.id>
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
Requires-Dist: pydantic<3.0.0,>=2.7.0
Requires-Dist: email-validator<3.0.0,>=2.0.0
Requires-Dist: python-json-logger<4.0.0,>=2.0.0
Provides-Extra: dev
Requires-Dist: coverage<8.0.0,>=7.4.4; extra == "dev"
Requires-Dist: mypy<2.0.0,>=1.15.0; extra == "dev"
Requires-Dist: pre-commit<4.0.0,>=3.7.0; extra == "dev"
Requires-Dist: pytest<10.0.0,>=9.0.3; extra == "dev"
Requires-Dist: pytest-asyncio<2.0.0,>=1.0.0; extra == "dev"
Requires-Dist: pytest-cov<8.0.0,>=7.0.0; extra == "dev"
Requires-Dist: ruff<1.0.0,>=0.6.7; extra == "dev"
Provides-Extra: fastapi
Requires-Dist: fastapi<1.0.0,>=0.115.0; extra == "fastapi"
Provides-Extra: stackauth
Requires-Dist: httpx<1.0.0,>=0.28.0; extra == "stackauth"
Provides-Extra: keycloak
Requires-Dist: httpx<1.0.0,>=0.28.0; extra == "keycloak"
Requires-Dist: pyjwt<3.0.0,>=2.13.0; extra == "keycloak"
Provides-Extra: ldap
Requires-Dist: ldap3<3.0.0,>=2.9.1; extra == "ldap"
Provides-Extra: saml
Requires-Dist: python3-saml<2.0.0,>=1.16.0; extra == "saml"
Requires-Dist: lxml<7.0.0,>=6.1.0; extra == "saml"
Provides-Extra: postgresql
Requires-Dist: asyncpg<1.0.0,>=0.30.0; extra == "postgresql"
Requires-Dist: sqlalchemy[asyncio]<3.0.0,>=2.0.0; extra == "postgresql"
Requires-Dist: passlib[bcrypt]<2.0.0,>=1.7.4; extra == "postgresql"
Requires-Dist: argon2-cffi<26.0.0,>=21.3.0; extra == "postgresql"
Requires-Dist: pyjwt<3.0.0,>=2.13.0; extra == "postgresql"
Requires-Dist: cryptography<49.0.0,>=48.0.1; extra == "postgresql"
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0; extra == "postgresql"
Requires-Dist: alembic<2.0.0,>=1.12.0; extra == "postgresql"
Provides-Extra: native
Requires-Dist: gl-iam-binary[postgresql]; extra == "native"
Provides-Extra: cli
Requires-Dist: click<9.0.0,>=8.1.0; extra == "cli"
Provides-Extra: cli-aws
Requires-Dist: click<9.0.0,>=8.1.0; extra == "cli-aws"
Requires-Dist: boto3<2.0.0,>=1.34.0; extra == "cli-aws"
Provides-Extra: cli-vault
Requires-Dist: click<9.0.0,>=8.1.0; extra == "cli-vault"
Requires-Dist: hvac<3.0.0,>=2.1.0; extra == "cli-vault"
Provides-Extra: cli-gcp
Requires-Dist: click<9.0.0,>=8.1.0; extra == "cli-gcp"
Requires-Dist: google-cloud-secret-manager<3.0.0,>=2.18.0; extra == "cli-gcp"
Provides-Extra: otel
Requires-Dist: opentelemetry-api<3.0.0,>=1.20.0; extra == "otel"
Requires-Dist: opentelemetry-sdk<3.0.0,>=1.20.0; extra == "otel"
Provides-Extra: django
Requires-Dist: django<6.0,>=4.0; extra == "django"
Requires-Dist: asgiref<4.0.0,>=3.5.0; extra == "django"
Provides-Extra: drf
Requires-Dist: django<6.0,>=4.0; extra == "drf"
Requires-Dist: asgiref<4.0.0,>=3.5.0; extra == "drf"
Requires-Dist: djangorestframework<4.0.0,>=3.14.0; extra == "drf"
Provides-Extra: all
Requires-Dist: opentelemetry-api<3.0.0,>=1.20.0; extra == "all"
Requires-Dist: opentelemetry-sdk<3.0.0,>=1.20.0; extra == "all"
Requires-Dist: fastapi<1.0.0,>=0.115.0; extra == "all"
Requires-Dist: httpx<1.0.0,>=0.28.0; extra == "all"
Requires-Dist: ldap3<3.0.0,>=2.9.1; extra == "all"
Requires-Dist: python3-saml<2.0.0,>=1.16.0; extra == "all"
Requires-Dist: lxml<7.0.0,>=6.1.0; extra == "all"
Requires-Dist: asyncpg<1.0.0,>=0.30.0; extra == "all"
Requires-Dist: sqlalchemy[asyncio]<3.0.0,>=2.0.0; extra == "all"
Requires-Dist: passlib[bcrypt]<2.0.0,>=1.7.4; extra == "all"
Requires-Dist: argon2-cffi<26.0.0,>=21.3.0; extra == "all"
Requires-Dist: pyjwt<3.0.0,>=2.13.0; extra == "all"
Requires-Dist: cryptography<49.0.0,>=48.0.1; extra == "all"
Requires-Dist: psycopg2-binary<3.0.0,>=2.9.0; extra == "all"
Requires-Dist: alembic<2.0.0,>=1.12.0; extra == "all"
Requires-Dist: django<6.0,>=4.0; extra == "all"
Requires-Dist: asgiref<4.0.0,>=3.5.0; extra == "all"
Requires-Dist: djangorestframework<4.0.0,>=3.14.0; extra == "all"
Requires-Dist: click<9.0.0,>=8.1.0; extra == "all"

# GL-IAM

## Description

A pluggable Identity and Access Management (IAM) SDK for GDP Labs applications. GL-IAM provides a unified interface for authentication, authorization, user management, and organization management following the Single Interface Multiple Implementation (SIMI) pattern.

### Key Features

- **Pluggable Authentication**: Support for Stack Auth, Keycloak (with LDAP/SAML federation), PostgreSQL, and custom providers
- **User Store Abstraction**: Flexible user storage with JIT (Just-In-Time) provisioning
- **Role-Based Access Control (RBAC)**: Comprehensive permission and role management
- **Multi-Factor Authentication (MFA)**: TOTP and other second-factor methods
- **Organization Management**: Multi-tenancy support for enterprise applications
- **FastAPI Integration**: Ready-to-use dependencies for FastAPI applications

---

## Installation

### Prerequisites

Mandatory:
1. Python 3.11+ — [Install here](https://www.python.org/downloads/)
2. pip — [Install here](https://pip.pypa.io/en/stable/installation/)
3. uv — [Install here](https://docs.astral.sh/uv/getting-started/installation/)

For PostgreSQL provider:
4. PostgreSQL 13+ — Recommended for production ([details](gl_iam/providers/postgresql/README.md#requirements))

Extras (required only for Artifact Registry installations):
1. gcloud CLI (for authentication) — [Install here](https://cloud.google.com/sdk/docs/install), then log in using:
   ```bash
   gcloud auth login
   ```

---

### Option 1: Install from Artifact Registry

This option requires authentication via the `gcloud` CLI.

```bash
uv pip install \
  --extra-index-url "https://oauth2accesstoken:$(gcloud auth print-access-token)@glsdk.gdplabs.id/gen-ai-internal/simple/" \
  gl-iam
```

With optional dependencies:

```bash
# With FastAPI integration
uv pip install "gl-iam[fastapi]"

# With Stack Auth provider
uv pip install "gl-iam[stackauth]"

# With LDAP provider
uv pip install "gl-iam[ldap]"

# With all providers
uv pip install "gl-iam[all]"
```

---

### Option 2: Install from PyPI

This option requires no authentication.
However, it installs the **binary wheel** version of the package, which is fully usable but **does not include source code**.

```bash
uv pip install gl-iam-binary
```

---

## Quick Start

### Basic Usage

```python
from gl_iam import IAMGateway
from gl_iam.providers.stackauth import StackAuthProvider

# Initialize with Stack Auth as full-stack provider
gateway = IAMGateway.from_fullstack_provider(
    provider=StackAuthProvider(
        api_url="https://api.stack-auth.com",
        project_id="your-project-id",
        secret_key="your-secret-key",
    )
)

# Authenticate a user
result = await gateway.authenticate(
    credentials={"email": "user@example.com", "password": "secret"}
)

if result.is_ok:
    user = result.user
    print(f"Authenticated: {user.display_name}")
```

### Mix-and-Match Providers

```python
from gl_iam import IAMGateway
from gl_iam.providers.ldap import LDAPAuthProvider
from gl_iam.providers.stackauth import StackAuthUserStore

# Use LDAP for authentication, Stack Auth for user storage
gateway = IAMGateway(
    auth_provider=LDAPAuthProvider(
        server_url="ldap://ad.company.com",
        base_dn="dc=company,dc=com",
    ),
    user_store=StackAuthUserStore(
        api_url="https://api.stack-auth.com",
        project_id="your-project-id",
    ),
    enable_jit_provisioning=True,  # Auto-create users on first login
)
```

### FastAPI Integration

```python
from fastapi import FastAPI, Depends
from gl_iam.fastapi import get_current_user, require_permission, require_role
from gl_iam.types import User

app = FastAPI()

@app.get("/profile")
async def get_profile(user: User = Depends(get_current_user)):
    return {"user_id": user.id, "email": user.email}

@app.delete("/admin/users/{user_id}")
async def delete_user(
    user_id: str,
    _: None = Depends(require_permission("users:delete")),
):
    # Only users with "users:delete" permission can access
    pass

@app.get("/admin/dashboard")
async def admin_dashboard(_: None = Depends(require_role("admin"))):
    # Only users with "admin" role can access
    pass
```

---

## Local Development Setup

### Prerequisites

1. Python 3.11+ — [Install here](https://www.python.org/downloads/)
2. pip — [Install here](https://pip.pypa.io/en/stable/installation/)
3. uv — [Install here](https://docs.astral.sh/uv/getting-started/installation/)
4. gcloud CLI — [Install here](https://cloud.google.com/sdk/docs/install), then log in using:

   ```bash
   gcloud auth login
   ```
5. Git — [Install here](https://git-scm.com/downloads)
6. Access to the [GDP Labs SDK GitHub repository](https://github.com/GDP-ADMIN/gl-sdk)

---

### 1. Clone Repository

```bash
git clone git@github.com:GDP-ADMIN/gl-sdk.git
cd gl-sdk/libs/gl-iam
```

---

### 2. Setup Authentication

Set the following environment variables to authenticate with internal package indexes:

```bash
export UV_INDEX_GEN_AI_INTERNAL_USERNAME=oauth2accesstoken
export UV_INDEX_GEN_AI_INTERNAL_PASSWORD="$(gcloud auth print-access-token)"
export UV_INDEX_GEN_AI_USERNAME=oauth2accesstoken
export UV_INDEX_GEN_AI_PASSWORD="$(gcloud auth print-access-token)"
```

---

### 3. Quick Setup

Run:

```bash
make setup
```

---

### 4. Activate Virtual Environment

```bash
source .venv/bin/activate
```

---

## Local Development Utilities

The following Makefile commands are available for quick operations:

### Install uv

```bash
make install-uv
```

### Install Pre-Commit

```bash
make install-pre-commit
```

### Install Dependencies

```bash
make install
```

### Update Dependencies

```bash
make update
```

### Run Tests

```bash
make test
```

---

## Architecture

GL-IAM follows the Single Interface Multiple Implementation (SIMI) pattern:

```
┌─────────────────────────────────────────────────────────────┐
│                       IAMGateway                            │
│  (Central Orchestrator - Coordinates all IAM operations)    │
└─────────────────────────────────────────────────────────────┘
                              │
        ┌─────────────────────┼─────────────────────┐
        ▼                     ▼                     ▼
┌───────────────┐    ┌───────────────┐    ┌───────────────┐
│ Authentication│    │  User Store   │    │   Session     │
│   Provider    │    │   Provider    │    │   Provider    │
└───────────────┘    └───────────────┘    └───────────────┘
        │                     │                     │
        ▼                     ▼                     ▼
┌───────────────┐    ┌───────────────┐    ┌───────────────┐
│  - Stack Auth │    │  - Stack Auth │    │  - Stack Auth │
│  - LDAP       │    │  - PostgreSQL │    │  - Redis      │
│  - SAML       │    │  - Custom     │    │  - JWT        │
│  - OAuth2     │    │               │    │               │
└───────────────┘    └───────────────┘    └───────────────┘
```

---

## Migration Guides

### Migrating from BOSA Core Auth

If you're currently using BOSA Core Authentication (`bosa-core[authentication]`) and want to migrate to GL-IAM, see the comprehensive migration guide:

📖 **[BOSA to GL-IAM Migration Guide](docs/migration/BOSA_TO_GL_IAM_MIGRATION_GUIDE.md)**

The guide covers:
- Step-by-step migration instructions
- API mapping reference (BOSA → GL-IAM)
- Data migration scripts
- Code examples for common patterns
- Testing and rollback strategies

---

## Contributing

Please refer to the [Python Style Guide](https://docs.google.com/document/d/1uRggCrHnVfDPBnG641FyQBwUwLoFw0kTzNqRm92vUwM/edit?usp=sharing)
for information about code style, documentation standards, and SCA requirements.

