{"templateId":"markdown","sharedDataIds":{"sidebar":"sidebar-ciam/sdks/sidebars.yaml"},"props":{"metadata":{"markdoc":{"tagList":["InteractiveLink","Notification","CodeBlockCustom","CodeItem"]},"type":"markdown"},"seo":{"title":"Protect your backend APIs with Go SDK","siteUrl":"https://developers.frontegg.com/","llmstxt":{"title":"Frontegg Developer Documentation","description":"Authentication, authorization, and user management for Customer Identity, plus Agen for SaaS and Agen for Work. Guides, SDKs, and API references.","sections":[{"title":"Customer Identity (CIAM)","description":"Auth, SSO, SCIM, entitlements, and user management — guides, SDKs, and APIs.","includeFiles":["ciam/**/*.md"],"excludeFiles":[]},{"title":"Agen for SaaS","description":"Agentic access and authorization for SaaS products.","includeFiles":["agen-for-saas/**/*.md"],"excludeFiles":[]},{"title":"Agen for Work","description":"Agentic access and authorization for internal and workforce use.","includeFiles":["agen-for-work/**/*.md"],"excludeFiles":[]},{"title":"Platform","description":"Shared platform overview.","includeFiles":["platform/**/*.md"],"excludeFiles":[]}],"excludeFiles":["internal-docs/**","ciam/guides/env-settings/inject-client-ip.md","CLAUDE.md","**/images/**"],"hide":false}},"dynamicMarkdocComponents":[],"compilationErrors":[],"ast":{"$$mdtype":"Tag","name":"article","attributes":{},"children":[{"$$mdtype":"Tag","name":"Heading","attributes":{"level":2,"id":"protect-your-backend-apis-with-go-sdk","__idx":0},"children":["Protect your backend APIs with Go SDK"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The Frontegg Go SDK lets you validate Frontegg JWTs, protect HTTP routes, check feature entitlements, and call the Frontegg API with idiomatic Go ergonomics."]},{"$$mdtype":"Tag","name":"InteractiveLink","attributes":{"href":"https://github.com/frontegg/go-sdk","target":"_blank","justifyContent":"center"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Check out the repo on GitHub"]}]},{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"Notification","attributes":{"title":"Prerequisites","type":"attention"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Go ≥ 1.24 and a Frontegg workspace with a ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Client ID"]}," and ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["API Key"]}," (Frontegg Portal → ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Settings → API Tokens"]},")."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"install-the-sdk","__idx":1},"children":["Install the SDK"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"header":{"controls":{"copy":{}}},"source":"go get github.com/frontegg/go-sdk\n"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"initialize","__idx":2},"children":["Initialize"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Initialize the SDK once at application startup with your workspace credentials. The package-level ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Init"]}," sets up a default client used by the HTTP middleware."]},{"$$mdtype":"Tag","name":"Notification","attributes":{"title":"Regions","type":"attention"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The SDK defaults to Frontegg's EU region. If you're running in another region, set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_API_GATEWAY_URL"]}," to your region's URL instead of ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["api.frontegg.com"]},"."]}]},{"$$mdtype":"Tag","name":"br","attributes":{},"children":[]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"github.com/frontegg/go-sdk\"\n\nfunc main() {\n\tfrontegg.Init(frontegg.Credentials{\n\t\tClientID: \"<YOUR_CLIENT_ID>\",\n\t\tAPIKey:   \"<YOUR_API_KEY>\",\n\t})\n\t// ...\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you prefer an explicit, dependency-injected client instead of the package-level default, construct one and build sub-clients from it:"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"client := frontegg.New(frontegg.Credentials{\n\tClientID: \"<YOUR_CLIENT_ID>\",\n\tAPIKey:   \"<YOUR_API_KEY>\",\n})\n\nidentity := client.Identity()\nentitlements := client.Entitlements()\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Notification","attributes":{"title":"Environment variables","type":"attention"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Credentials can also be provided through the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_CLIENT_ID"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_API_KEY"]}," environment variables. Values passed in code take precedence."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"protect-backend-routes","__idx":3},"children":["Protect backend routes"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Use the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WithAuthentication"]}," middleware to protect your routes. It reads the token from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization: Bearer <token>"]}," header or the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-api-key"]}," header, validates it, optionally enforces roles and permissions, and stores the decoded user on the request context."]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import (\n\t\"net/http\"\n\n\t\"github.com/frontegg/go-sdk\"\n\t\"github.com/frontegg/go-sdk/middleware\"\n)\n\nfunc main() {\n\tfrontegg.Init(frontegg.Credentials{\n\t\tClientID: \"<YOUR_CLIENT_ID>\",\n\t\tAPIKey:   \"<YOUR_API_KEY>\",\n\t})\n\n\t// This route is accessible only to authenticated users with the \"admin\" role.\n\tprotected := frontegg.WithAuthentication(middleware.Options{\n\t\tRoles:       []string{\"admin\"},\n\t\tPermissions: []string{\"fe.secure.read\"},\n\t})\n\n\tmux := http.NewServeMux()\n\tmux.Handle(\"/protected\", protected(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tuser, _ := middleware.UserFromContext(r.Context())\n\t\t// user.ID(), user.Email, user.TenantID, user.Roles, user.Permissions\n\t\t_, _ = w.Write([]byte(\"hello \" + user.Email))\n\t})))\n\n\t_ = http.ListenAndServe(\":8080\", mux)\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Behavior"]}]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":["No credentials → ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401 Unauthenticated"]},"."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["Invalid token, or missing required role/permission → the error's status code (",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["401"]}," for authentication failures, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["403"]}," for authorization failures)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":["On success, the decoded entity is available via ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["middleware.UserFromContext(ctx)"]},"."]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Roles"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Permissions"]}," are satisfied when the token contains ",{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["at least one"]}," of the listed values."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The middleware works with the standard library and any router built on ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["net/http"]}," (chi, gorilla, ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["http.ServeMux"]},", and others)."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"using-an-explicit-client","__idx":4},"children":["Using an explicit client"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["If you don't want to use the package-level default, pass an identity client directly:"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"guard := middleware.WithAuthentication(client.Identity(), middleware.Options{\n\tRoles: []string{\"admin\"},\n})\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"use-access-tokens","__idx":5},"children":["Use access tokens"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["When you use M2M authentication, access tokens are cached automatically. The in-memory cache is the default. To share a cache across multiple instances, use the Redis backend (only applications that import it pull in the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["go-redis"]}," dependency):"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import (\n\t\"github.com/redis/go-redis/v9\"\n\t\"github.com/frontegg/go-sdk/cache/redisstore\"\n)\n\nrdb := redis.NewClient(&redis.Options{Addr: \"localhost:6379\"})\nstore := redisstore.New[MyType](rdb) // implements cache.Cache[MyType]\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"frontegg-clients","__idx":6},"children":["Frontegg clients"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Frontegg provides various clients for seamless integration with the Frontegg APIs. The entitlements client can be used to determine whether an authorized user or tenant is entitled to a particular feature or permission. This client is discussed in detail in ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/ciam/sdks/backend/go/entitlements"},"children":["Entitlements quickstart"]},"."]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Frontegg's Managed Audit Logs feature allows collecting custom audit logs that are specific for your application and displaying these in Frontegg's ",{"$$mdtype":"Tag","name":"a","attributes":{"href":"/ciam/guides/admin-portal/intro"},"children":["self-service component"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"create-a-new-audits-client","__idx":7},"children":["Create a new audits client"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"github.com/frontegg/go-sdk/audits\"\n\nac := client.Audits()\nif err := ac.Init(ctx, \"<CLIENT_ID>\", \"<AUDITS_KEY>\"); err != nil {\n\tlog.Fatal(err)\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"sending-audits","__idx":8},"children":["Sending audits"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"_ = ac.SendAudit(ctx, audits.SendAuditParams{\n\tTenantID: \"my-tenant-id\",\n\tSeverity: audits.SeverityMedium,\n\tFields: map[string]any{\n\t\t\"user\":     \"info@frontegg.com\",\n\t\t\"resource\": \"Portal\",\n\t\t\"action\":   \"Login\",\n\t\t\"ip\":       \"1.2.3.4\",\n\t},\n})\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"fetching-audits","__idx":9},"children":["Fetching audits"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"page, err := ac.GetAudits(ctx, audits.GetAuditsParams{\n\tTenantID:      \"my-tenant-id\",\n\tFilter:        \"any-text-filter\",\n\tSortBy:        \"createdAt\",\n\tSortDirection: \"desc\",\n\tOffset:        0,\n\tCount:         50,\n})\n// page.Data, page.Total\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The audits client also exposes ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GetAuditsStats"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["GetAuditsMetadata"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["SetAuditsMetadata"]},"."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"events","__idx":10},"children":["Events"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"github.com/frontegg/go-sdk/events\"\n\nev := client.Events(auth) // auth: an initialized authenticator\n\neventID, err := ev.Send(ctx, \"my-tenant-id\", events.EventTrigger{\n\tEventKey: \"user.invited\",\n\tData: events.EventProperties{\n\t\tTitle:       \"You're invited\",\n\t\tDescription: \"Join the Acme team\",\n\t},\n})\n\nstatus, err := ev.GetStatus(ctx, eventID)\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"working-with-the-rest-api","__idx":11},"children":["Working with the REST API"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Frontegg provides a comprehensive REST API for your application. In order to use the API from your backend it is required to initialize the client and the authenticator which maintains the backend to backend session."]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"github.com/frontegg/go-sdk/httpclient\"\n\nauth := client.NewAuthenticator()\nif err := auth.Init(ctx, \"<YOUR_CLIENT_ID>\", \"<YOUR_API_KEY>\"); err != nil {\n\tlog.Fatal(err)\n}\n\napi := client.HTTPClient(auth, httpclient.WithBaseURL(\"https://api.frontegg.com\"))\n\nresp, err := api.Post(ctx, \"identity/resources/auth/v1/user\",\n\tmap[string]string{\n\t\t\"email\":    \"johndoe@acme.com\",\n\t\t\"password\": \"my-super-duper-password\",\n\t},\n\t// Optional per-request headers. \"frontegg-vendor-host\" rewrites the host.\n\tmap[string]string{\"frontegg-vendor-host\": \"acme.frontegg\"},\n)\nif err != nil {\n\tlog.Fatal(err)\n}\n\nvar user map[string]any\n_ = resp.JSON(&user)\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Get"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Post"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Put"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Patch"]},", and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Delete"]}," are available; each returns a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["*Response"]}," with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["StatusCode"]},", ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Header"]},", and a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["JSON(&v)"]}," helper."]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"hosted-login-oauth-21--pkce","__idx":12},"children":["Hosted login (OAuth 2.1 + PKCE)"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The hosted-login flow uses PKCE, as required by OAuth 2.1. ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["RequestAuthorize"]}," returns a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["code_verifier"]}," that you must persist (for example, in the user's session keyed by ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["state"]},") and pass back to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["CodeExchange"]},"."]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"github.com/frontegg/go-sdk/hostedlogin\"\n\nhl := client.HostedLogin(\"https://your-app.com/oauth/callback\")\n\n// 1. Build the authorization URL and keep the verifier.\nauthReq, err := hl.RequestAuthorize(ctx, \"csrf-state-token\")\n//    Redirect the user to authReq.URL.\n//    Store authReq.CodeVerifier, keyed by authReq.State.\n\n// 2. On the callback (with ?code= and ?state= from the query string):\nres, err := hl.CodeExchange(ctx, code, state, savedCodeVerifier)\n//    res.User          → the decoded user profile\n//    res.AccessToken   → access token\n//    res.RefreshToken  → refresh token\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Notification","attributes":{"title":"Redirect URI","type":"attention"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["The ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["redirect_uri"]}," you pass to ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["HostedLogin"]}," must exactly match an allowed callback configured on your Frontegg application."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"validating-jwt","__idx":13},"children":["Validating JWT"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Frontegg provides an identity client that can be utilized for validating Frontegg JWTs outside the middleware flow."]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"github.com/frontegg/go-sdk/identity\"\n\nident := client.Identity()\n\nuser, err := ident.ValidateToken(ctx, bearerToken, &identity.ValidateTokenOptions{\n\tRoles:                   []string{\"admin\"},\n\tPermissions:             []string{\"fe.secure.read\"},\n\tWithRolesAndPermissions: true, // hydrate roles & permissions on the entity\n}, identity.JWTHeader)\nif err != nil {\n\t// handle authentication / authorization failure\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["ValidateToken"]}," takes the header type as its last argument:"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["identity.JWTHeader"]}," — a Frontegg JWT (from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["Authorization"]}," header)."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["identity.AccessTokenHeader"]}," — an API key (from the ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["x-api-key"]}," header)."]}]},{"$$mdtype":"Tag","name":"Notification","attributes":{"title":"Permissions in JWTs","type":"attention"},"children":[{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Some JWTs do not include permissions in their payload. Permissions are required for entitlement checks, so set ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["WithRolesAndPermissions: true"]}," when you need them."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":4,"id":"step-up-authentication","__idx":14},"children":["Step-up authentication"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Verify that a user has completed step-up (MFA) authentication, optionally within a maximum session age:"]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"// Require step-up.\nuser, err := ident.ValidateToken(ctx, token, &identity.ValidateTokenOptions{\n\tStepUp: &identity.StepUpOptions{},\n}, identity.JWTHeader)\n\n// Require step-up performed within the last hour.\nuser, err = ident.ValidateToken(ctx, token, &identity.ValidateTokenOptions{\n\tStepUp: &identity.StepUpOptions{MaxAge: 3600},\n}, identity.JWTHeader)\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"configuration","__idx":15},"children":["Configuration"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Service URLs default to the public Frontegg gateway and can be overridden via environment variables — useful for EU/regional or self-hosted deployments."]},{"$$mdtype":"Tag","name":"div","attributes":{"className":"md-table-wrapper"},"children":[{"$$mdtype":"Tag","name":"table","attributes":{"className":"md"},"children":[{"$$mdtype":"Tag","name":"thead","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Variable"},"children":["Variable"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Default"},"children":["Default"]},{"$$mdtype":"Tag","name":"th","attributes":{"data-label":"Description"},"children":["Description"]}]}]},{"$$mdtype":"Tag","name":"tbody","attributes":{},"children":[{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_CLIENT_ID"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["—"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Vendor client ID (used when not passed in code)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_API_KEY"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["—"]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Vendor API key (used when not passed in code)"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_API_GATEWAY_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["https://api.frontegg.com"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Base URL for all services"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_AUTHENTICATOR_NUMBER_OF_TRIES"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["3"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Number of authentication retry attempts"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_IDENTITY_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/identity"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Identity service URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_ENTITLEMENTS_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/entitlements"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Entitlements service URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_AUDITS_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/audits/"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Audits service URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_EVENT_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/event"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Events service URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_OAUTH_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/oauth"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["OAuth service URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_VENDORS_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/vendors"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Vendors service URL"]}]},{"$$mdtype":"Tag","name":"tr","attributes":{},"children":[{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["FRONTEGG_METADATA_SERVICE_URL"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":[{"$$mdtype":"Tag","name":"code","attributes":{},"children":["<base>/metadata/"]}]},{"$$mdtype":"Tag","name":"td","attributes":{},"children":["Metadata service URL"]}]}]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"error-handling","__idx":16},"children":["Error handling"]},{"$$mdtype":"Tag","name":"p","attributes":{},"children":["Errors are returned as values and are inspectable with ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errors.Is"]}," and ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["errors.As"]},". Identity errors also carry an HTTP status code."]},{"$$mdtype":"Tag","name":"CodeBlockCustom","attributes":{"tabs":["go"]},"children":[{"$$mdtype":"Tag","name":"CodeItem","attributes":{},"children":[{"$$mdtype":"Tag","name":"CodeBlock","attributes":{"data-language":"go","header":{"controls":{"copy":{}}},"source":"import \"errors\"\n\n_, err := ident.ValidateToken(ctx, token, opts, identity.JWTHeader)\n\nswitch {\ncase errors.Is(err, identity.ErrInsufficientRole):       // 403\ncase errors.Is(err, identity.ErrInsufficientPermission): // 403\ncase errors.Is(err, identity.ErrFailedToAuthenticate):   // 401\n}\n\n// Inspect the status code directly:\nvar sce *identity.StatusCodeError\nif errors.As(err, &sce) {\n\thttp.Error(w, sce.Message, sce.StatusCode)\n}\n","lang":"go"},"children":[]}]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"conventions","__idx":17},"children":["Conventions"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Context:"]}," every method that performs I/O takes a ",{"$$mdtype":"Tag","name":"code","attributes":{},"children":["context.Context"]}," as its first argument."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Concurrency:"]}," all clients are safe for concurrent use."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Errors:"]}," returned as values; no panics for expected failures."]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"strong","attributes":{},"children":["Token refresh:"]}," the authenticator refreshes the vendor token automatically before it expires."]}]},{"$$mdtype":"Tag","name":"Heading","attributes":{"level":3,"id":"related-documentation","__idx":18},"children":["Related documentation"]},{"$$mdtype":"Tag","name":"ul","attributes":{},"children":[{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"/ciam/sdks/backend/go/entitlements"},"children":["Go Entitlements"]}," — feature and permission checks"]},{"$$mdtype":"Tag","name":"li","attributes":{},"children":[{"$$mdtype":"Tag","name":"a","attributes":{"href":"https://github.com/frontegg/go-sdk"},"children":["Source & issues"]}," — Go SDK on GitHub"]}]}]},"headings":[{"value":"Protect your backend APIs with Go SDK","id":"protect-your-backend-apis-with-go-sdk","depth":2},{"value":"Install the SDK","id":"install-the-sdk","depth":3},{"value":"Initialize","id":"initialize","depth":3},{"value":"Protect backend routes","id":"protect-backend-routes","depth":3},{"value":"Using an explicit client","id":"using-an-explicit-client","depth":4},{"value":"Use access tokens","id":"use-access-tokens","depth":3},{"value":"Frontegg clients","id":"frontegg-clients","depth":3},{"value":"Create a new audits client","id":"create-a-new-audits-client","depth":4},{"value":"Sending audits","id":"sending-audits","depth":4},{"value":"Fetching audits","id":"fetching-audits","depth":4},{"value":"Events","id":"events","depth":4},{"value":"Working with the REST API","id":"working-with-the-rest-api","depth":3},{"value":"Hosted login (OAuth 2.1 + PKCE)","id":"hosted-login-oauth-21--pkce","depth":3},{"value":"Validating JWT","id":"validating-jwt","depth":3},{"value":"Step-up authentication","id":"step-up-authentication","depth":4},{"value":"Configuration","id":"configuration","depth":3},{"value":"Error handling","id":"error-handling","depth":3},{"value":"Conventions","id":"conventions","depth":3},{"value":"Related documentation","id":"related-documentation","depth":3}],"frontmatter":{"seo":{"title":"Protect your backend APIs with Go SDK"}},"lastModified":"2026-06-25T15:13:53.000Z","pagePropGetterError":{"message":"","name":""}},"slug":"/ciam/sdks/backend/go/go-integrate","userData":{"isAuthenticated":false,"teams":["anonymous"]},"isPublic":true}