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-sidecarcurl -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-sidecardocker run -d -p 50051:50051 ghcr.io/coresdk-dev/sidecar:latestNo 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-engine3. 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/me5. 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 deniedLoad 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 ownNext steps
- Full FastAPI example → — auth, RBAC, ABAC, multi-tenancy in one app
- Authentication → — JWT/OIDC, JWKS rotation
- Authorization & Policy → — writing Rego policies
- Observability → —
@trace, PII masking, OTel export - Configuration reference →