### Start server with provisioning API enabled Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/provisioning/provisioning.md Starts the server with the provisioning API enabled, using the development PKI certificates. Requires the XOLO_SECRET_KEY environment variable. ```bash XOLO_SECRET_KEY=$(openssl rand -hex 32) \ XOLO_PROVISIONNING_API_ENABLED=true \ XOLO_PROVISIONNING_API_TLS_CERT_FILE=dev-pki/server.crt \ XOLO_PROVISIONNING_API_TLS_KEY_FILE=dev-pki/server.key \ XOLO_PROVISIONNING_API_TLS_CLIENT_CA_FILE=dev-pki/ca.crt \ bin/server ``` -------------------------------- ### PreRequest access control example (time-restriction) Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/plugins.md Example PreRequest implementation that parses configuration, checks if the current time is allowed, and rejects the request with a French rejection reason if not. Returns Allowed=false on config error. ```go func (p *Plugin) PreRequest(_ context.Context, in *proto.PreRequestInput) (*proto.PreRequestOutput, error) { cfg, err := parseConfig(in.GetCtx().GetConfigJson()) if err != nil { return &proto.PreRequestOutput{Allowed: false, RejectionReason: "config error"}, nil } allowed, _ := isAllowed(time.Now(), cfg) if !allowed { return &proto.PreRequestOutput{ Allowed: false, RejectionReason: "Accès refusé : hors des plages horaires autorisées.", }, nil } return &proto.PreRequestOutput{Allowed: true}, nil } ``` -------------------------------- ### EventQL Query Examples Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/concepts/eventql.md A table of example EventQL queries and their intents, covering various filtering patterns such as type, severity, provider, source, model, and actor. ```text {} ``` ```text {type="proxy.request"} ``` ```text {severity=~"warning|error"} ``` ```text {type="auth.login.failed"} | provider="oidc" ``` ```text {source!="platform"} ``` ```text {type=~"provider\..*"} ``` ```text {type="proxy.request"} | model=~"gpt-4.*" |~ "timeout" ``` ```text {} | actor_id="c8p2..." ``` -------------------------------- ### Use structured logging Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/plugins.md Example of using structured logging with slog to log the selected model and power level. ```go slog.InfoContext(ctx, "my-plugin: selected model", slog.String("model", selected), slog.Float64("power_level", powerLevel), ) ``` -------------------------------- ### Parse config defensively Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/plugins.md Example of parsing plugin config defensively, logging a warning and failing open on error. ```go cfg, err := ParseConfig(in.GetCtx().GetConfigJson()) if err != nil { slog.WarnContext(ctx, "my-plugin: bad config, skipping") return &proto.PreRequestOutput{Allowed: true}, nil // fail open } ``` -------------------------------- ### Development setup commands Source: https://github.com/xolo-gateway/xolo/blob/main/CONTRIBUTING.md Commands for building, generating, watching, and testing the Xolo project. Requires Go, GNU make, and Docker for integration tests. ```bash make build # builds bin/server make generate # templ + tailwind; required after editing .templ files make watch # hot-reload dev server (uses .env) go test ./... # unit tests, SQLite only, no Docker needed make test-integration # store suite on SQLite AND PostgreSQL (needs Docker) ``` -------------------------------- ### Build and run Xolo from source Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/index.md Clones the repository, copies the environment template, edits configuration, and builds the server and plugins. The make build command compiles the server, frontend, and all plugins under plugins/. For hot reload during development, use make watch. ```bash git clone https://github.com/xolo-gateway/xolo.git cd xolo cp .env.dist .env # éditez .env : XOLO_SECRET_KEY, XOLO_HTTP_AUTHN_DEFAULT_ADMINS, un fournisseur d'auth… make build # compile bin/server et les plugins dans bin/plugins/ make CMD='bin/server' run-with-env ``` -------------------------------- ### Brute-Force Alert Rule Example Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/concepts/eventql.md Example alert rule configuration for detecting brute-force attacks: more than 5 failed logins in 5 minutes, with org scope requiring events:write permission. ```text Requête : {type="auth.login.failed"} Agrégation : count Fenêtre : 5m Condition : > 5 Portée : org (nécessite events:write) ``` -------------------------------- ### Initialize Plugin with Host Service Broker Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/plugins.md Implements the Initialize method to receive the host service broker, dial the host service, and create a client for accessing host methods. ```go func (p *Plugin) Initialize(ctx context.Context, req *proto.InitializeRequest) (*proto.InitializeResponse, error) { conn, err := p.broker.Dial(req.HostServiceBrokerId) if err != nil { return nil, err } p.host = proto.NewXoloHostServiceClient(conn) return &proto.InitializeResponse{}, nil } ``` -------------------------------- ### Personal Alert Example Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/concepts/eventql.md Example of a personal alert: user wants to be alerted when exceeding 100 proxy requests in an hour, using count(1h) > 100 on {type="proxy.request"} with personal scope. ```text count(1h) > 100 ``` ```text {type="proxy.request"} ``` -------------------------------- ### Initial API calls with client certificate Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/provisioning/provisioning.md Shows how to call the provisioning API with client certificates. The first call without a client certificate is refused, then a tenant ID is fetched, and finally an organization and its owner are created. ```bash CURL="curl -s --cacert dev-pki/ca.crt --cert dev-pki/client.crt --key dev-pki/client.key" # Refusé : aucun certificat client curl -sk https://localhost:3003/v1/permissions # Accepté : on récupère d'abord l'identifiant du tenant $CURL "https://localhost:3003/v1/tenants?slug=default" TENANT=… # l'identifiant lu ci-dessus # Puis on crée une organisation et son propriétaire $CURL -X POST "https://localhost:3003/v1/tenants/$TENANT/organizations" \ -d '{"slug":"acme","name":"Acme","owner":{"provider":"openid-connect","subject":"sub-123","email":"owner@acme.tld","displayName":"Owner"}}' ``` -------------------------------- ### Serve Plugin With HTTP UI Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/plugins.md Starts the plugin server with an HTTP UI for config editor and analytics. Requires a UI handler and a plugin name. ```go func main() { pluginsdk.ServeWithUI(&Plugin{}, "my-plugin", newUIHandler()) } ``` -------------------------------- ### RESOLVE_MODEL example - dummy model synthetic response Source: https://github.com/xolo-gateway/xolo/blob/main/docs/fr/administration/installation/plugins.md Example implementation of ResolveModel that returns a synthetic response for a trigger model. It parses config, checks if the requested model is a trigger model, and returns a formatted string as ResponseContent. ```go func (p *Plugin) ResolveModel(ctx context.Context, in *proto.ResolveModelInput) (*proto.ResolveModelOutput, error) { cfg, err := ParseConfig(in.GetCtx().GetConfigJson()) if err != nil { return &proto.ResolveModelOutput{}, nil } localModel := localModelName(in.GetRequestedModel()) if !cfg.isTriggerModel(localModel) { return &proto.ResolveModelOutput{}, nil // pass through } content := fmt.Sprintf("**[dummy-model]**\n\n- Modèle invoqué : %s\n", in.GetRequestedModel()) return &proto.ResolveModelOutput{ResponseContent: content}, nil } ``` -------------------------------- ### GET /v1/tenants/{tenantID} Source: https://github.com/xolo-gateway/xolo/blob/main/internal/provisionning/README.md Retrieves a tenant by its ID. ```APIDOC ## GET /v1/tenants/{tenantID} ### Description Retrieves a tenant by its ID. ### Method GET ### Endpoint /v1/tenants/{tenantID} ### Parameters #### Path Parameters - **tenantID** (string) - Required - The unique identifier of the tenant. ``` -------------------------------- ### Start server on generated database Source: https://github.com/xolo-gateway/xolo/blob/main/cmd/seed/README.md Launches the server with environment variables pointing to the seeded database. The `XOLO_SECRET_KEY` must match the one used during seeding because API keys are encrypted with AES-GCM using this key. ```bash XOLO_STORAGE_DATABASE_DSN=e2e.sqlite \ XOLO_SECRET_KEY=0e2ec2e6d5aa74c1b96c65d1b4a0f4d9ad48c6b1f3ff7a1c5f0f5f2ae4c1d3b7 \ XOLO_HTTP_ADDRESS=:3002 XOLO_HTTP_BASE_URL=http://localhost:3002 \ XOLO_HTTP_SESSION_KEYS=abcdefghijklmnopqrstuvwxyz000002 \ bin/server ``` -------------------------------- ### Run server with mTLS and test endpoints with curl Source: https://github.com/xolo-gateway/xolo/blob/main/internal/provisionning/README.md Starts the server with the development PKI and tests the provisioning API. The server refuses requests without a client certificate, and accepts requests presenting the client certificate. The TENANT variable must be set to the identifier returned by the lookup endpoint before creating an organization. ```bash XOLO_SECRET_KEY=$(openssl rand -hex 32) \ XOLO_PROVISIONNING_API_ENABLED=true \ XOLO_PROVISIONNING_API_TLS_CERT_FILE=dev-pki/server.crt \ XOLO_PROVISIONNING_API_TLS_KEY_FILE=dev-pki/server.key \ XOLO_PROVISIONNING_API_TLS_CLIENT_CA_FILE=dev-pki/ca.crt \ bin/server # Refused: no client certificate curl -sk https://localhost:3003/v1/permissions # Accepted curl -s --cacert dev-pki/ca.crt --cert dev-pki/client.crt --key dev-pki/client.key \ "https://localhost:3003/v1/tenants?slug=default" # Then, with the identifier it returned: TENANT=... # the id read above curl -s --cacert dev-pki/ca.crt --cert dev-pki/client.crt --key dev-pki/client.key \ -X POST "https://localhost:3003/v1/tenants/$TENANT/organizations" \ -d '{"slug":"acme","name":"Acme","owner":{"provider":"openid-connect","subject":"sub-123","email":"owner@acme.tld","displayName":"Owner"}}' ``` -------------------------------- ### GET /v1/tenants/{tenantID}/users/{userID} Source: https://github.com/xolo-gateway/xolo/blob/main/internal/provisionning/README.md Retrieves a specific user. ```APIDOC ## GET /v1/tenants/{tenantID}/users/{userID} ### Description Retrieves a specific user. ### Method GET ### Endpoint /v1/tenants/{tenantID}/users/{userID} ### Parameters #### Path Parameters - **tenantID** (string) - Required - The unique identifier of the tenant. - **userID** (string) - Required - The unique identifier of the user. ``` -------------------------------- ### GET /v1/tenants/{tenantID}/organizations/{orgID} Source: https://github.com/xolo-gateway/xolo/blob/main/internal/provisionning/README.md Retrieves an organization by its ID. ```APIDOC ## GET /v1/tenants/{tenantID}/organizations/{orgID} ### Description Retrieves an organization by its ID. ### Method GET ### Endpoint /v1/tenants/{tenantID}/organizations/{orgID} ### Parameters #### Path Parameters - **tenantID** (string) - Required - The unique identifier of the tenant. - **orgID** (string) - Required - The unique identifier of the organization. ``` -------------------------------- ### Make commands for build, run, test, and release Source: https://github.com/xolo-gateway/xolo/blob/main/AGENTS.md Common development commands for the Xolo gateway. Build requires running `make generate` after changing .templ files. Tests use SQLite by default; integration tests need Docker and are run by the `integration` CI job; e2e tests run a real server with a fake provider and are run by the `e2e` CI job. `make seed` generates a deterministic E2E fixture. ```bash # Build make build # builds bin/server make generate # runs templ + tailwind (required before build if .templ files changed) # Run (with .env) make watch # hot-reload dev server via modd make CMD='bin/server' run-with-env # Test go test ./... # unit tests, SQLite only, no Docker needed go test ./internal/adapter/memory/... # single package make test # root module + pkg/pluginsdk (nested Go module, not covered by ./...) make test-integration # store suite on BOTH backends (PostgreSQL via testcontainers, needs Docker; run by the `integration` CI job) make test-e2e # real server + fake provider over HTTP (see test/e2e/README.md; run by the `e2e` CI job) make seed # generates e2e.sqlite, a deterministic E2E fixture (see cmd/seed/README.md) # Release make goreleaser # snapshot release ``` -------------------------------- ### Example Signed-off-by line Source: https://github.com/xolo-gateway/xolo/blob/main/CONTRIBUTING.md Git appends this line to the commit message when signing off. ```text Signed-off-by: Firstname Lastname ```