Skip to main content
CoreSDK
Getting Started

Quickstart

Add CoreSDK to your service in under 5 minutes.

Quickstart

Get CoreSDK running with full auth, policy, and tracing in about 5 minutes.

1. Start the sidecar

The sidecar handles JWT verification, Rego policy evaluation, and OTel export. Your app talks to it over local gRPC.

curl -LO https://github.com/coresdk-dev/core/releases/latest/download/coresdk-sidecar-aarch64-apple-darwin.tar.gz
tar xf coresdk-sidecar-aarch64-apple-darwin.tar.gz
./coresdk-sidecar
curl -LO https://github.com/coresdk-dev/core/releases/latest/download/coresdk-sidecar-x86_64-unknown-linux-gnu.tar.gz
tar xf coresdk-sidecar-x86_64-unknown-linux-gnu.tar.gz
./coresdk-sidecar
docker run -d -p 50051:50051 ghcr.io/coresdk-dev/sidecar:latest

No sidecar yet? Set fail_mode = "open" (the default) and your app still runs — requests are allowed through. You can develop locally without the sidecar.

2. Install the SDK

pip install "coresdk[fastapi]"
# or: pip install "coresdk[flask]"
# or: pip install "coresdk[django]"
cargo add coresdk-engine

3. Add to your app

from fastapi import FastAPI, Request
from coresdk import CoreSDKClient, SDKConfig
from coresdk.middleware.fastapi import CoreSDKMiddleware
from coresdk.tracing.decorator import trace

_sdk = CoreSDKClient(SDKConfig(
    sidecar_addr="[::1]:50051",
    tenant_id="acme-corp",
    fail_mode="open",        # allow on sidecar error
))

class SDKAdapter:
    config = _sdk.config
    def authorize_sync(self, token, **kw):
        return _sdk.validate_token(token, **kw)

app = FastAPI()
app.add_middleware(
    CoreSDKMiddleware,
    sdk=SDKAdapter(),
    exclude_paths=["/healthz"],
)

@app.get("/me")
@trace(intent="get-current-user")
async def me(request: Request):
    # Claims set by middleware on request.state.coresdk_user
    return request.state.coresdk_user or {"sub": "anonymous"}
from flask import Flask, g
from coresdk import CoreSDKClient, SDKConfig
from coresdk.middleware.flask import CoreSDKFlask
from coresdk.tracing.decorator import trace

_sdk = CoreSDKClient(SDKConfig(
    sidecar_addr="[::1]:50051",
    tenant_id="acme-corp",
    fail_mode="open",
))

app = Flask(__name__)
CoreSDKFlask(_sdk, app)    # registers before_request + error handler

@app.get("/me")
@trace(intent="get-current-user")
def me():
    # Claims set by middleware on flask.g.claims
    return g.claims or {"sub": "anonymous"}
# settings.py
MIDDLEWARE = [
    "coresdk.django.CoreSDKMiddleware",
    # ... your other middleware
]
CORESDK = {
    "sidecar_addr": "[::1]:50051",
    "tenant_id": "acme-corp",
    "fail_mode": "open",
}
# views.py
from django.http import JsonResponse
from coresdk.tracing.decorator import trace

@trace(intent="get-current-user")
def me(request):
    # Claims set by middleware on request.coresdk_claims
    return JsonResponse(request.coresdk_claims or {"sub": "anonymous"})
use axum::{Router, routing::get, extract::Extension, Json};
use coresdk_engine::{Engine, EngineConfig};
use coresdk_engine::axum::auth_layer;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    let engine = Engine::from_env()?;

    let app = Router::new()
        .route("/me", get(me))
        .layer(auth_layer(engine.auth()));   // validates JWT on every request

    axum::serve(
        tokio::net::TcpListener::bind("0.0.0.0:3000").await?,
        app,
    ).await?;
    Ok(())
}

async fn me(Extension(user): Extension<coresdk_engine::axum::CurrentUser>)
    -> Json<serde_json::Value>
{
    Json(serde_json::json!({
        "user_id": user.sub,
        "tenant":  user.tenant_id,
        "roles":   user.roles,
    }))
}

4. Try it

# No token → 401 with RFC 9457 error
curl http://localhost:8000/me

# With token → claims returned (fail-open without real JWKS)
curl -H "Authorization: Bearer my-token" http://localhost:8000/me

5. Add role-based access control

from fastapi import Depends, HTTPException, Request

def require_role(role: str):
    def _check(request: Request):
        user = request.state.coresdk_user or {}
        if role not in user.get("roles", []):
            raise HTTPException(status_code=403, detail={
                "type":   "https://coresdk.io/errors/forbidden",
                "title":  "Forbidden",
                "status": 403,
                "detail": f"Role '{role}' required",
            })
        return user
    return Depends(_check)

@app.post("/products")
@trace(intent="create-product")
async def create_product(body: dict, _=require_role("editor")):
    ...

6. Evaluate a Rego policy (ABAC)

result = _sdk.evaluate_policy("data.authz.allow", {
    "tenant_id": "acme-corp",
    "subject":   "alice",
    "action":    "read",
    "resource":  "documents/doc-1",
    "resource_owner": "alice",
    "context": {"roles": ["viewer"]},
})
# → True if policy allows, False if denied

Load a Rego bundle:

export CORESDK_POLICY_DIR=./policy
# policy/authz.rego
package authz
import rego.v1

default allow := false
allow if { "admin" in input.context.roles }
allow if { input.resource_owner == input.subject }   # owner can always read their own

Next steps

On this page