# Okta login

People sign in to Straza with their Okta account, in a browser on the machine they enroll, and strazad trusts your Okta authorization server's ID tokens.

- Who: You, as the Okta admin and the Straza admin
- Where: The Okta Admin Console, strazad's configuration file, and a terminal on a person's machine
- Profile: Enterprise

In short: People sign in to Straza with their Okta account, in a browser on the machine they enroll, and Straza never holds their password. You create a native app with PKCE and a fixed 127.0.0.1 redirect port, and point strazad at your authorization server. Your IGA, or Okta itself, provisions the people over SCIM.


YoumakeOktatheloginproviderofanenterpriseStraza,astheadminofboth.YoucreateanativeappforStrazaintheOktaAdminConsole,pointstrazadatyourauthorizationserver,andenrollamachine.AttheendpeoplesignintoStrazawiththeirOktaaccount,inabrowseronthemachinetheyenroll,andStrazaneverholdstheirpassword.NosteponthispagehasbeenfiredagainstarealOktaorgyet.TheOktasettingsfollowOkta'sdocumentation,andtheStrazasidefollowsthecode.[Keycloaklogin](https://docs.straza.ai/guides/connect-identity/keycloak-login/index.md)istheproviderthatwaswalkedendtoend.##Beforeyoustart{.nostep}-Oktaadministrationforappintegrationsandfortheauthorizationserveryousigninat.-Accesstostrazad'sconfiguration,andaperson'sLinuxmachinewiththe`straza`package,as[Enrollamachine](https://docs.straza.ai/guides/govern-an-agent/enroll-a-machine/index.md)describes.-AnidentitymanagerthatprovisionspeopleintoStrazaoverSCIM,becausetheenterpriseprofilecreatesnouseratsign-in.Oktacandothatitself,as[Okta](https://docs.straza.ai/guides/connect-identity/okta/index.md)shows.-Afreeportfrom1024to65535onpeople'smachinesforthesign-inanswer.Theexamplesuse8765.##WhatdependsonOkta{.nostep}Mostofthesign-inisStraza'sownandworksalikeateveryprovider.`strazaservice`runsthebrowsersign-inwithPKCE,namestheenrollingkeyinthenonce,andtakestheansweronlyon127.0.0.1.strazadchecksthatthesign-innamesthatkeyandisatmost10minutesold,applies`governance.minSignIn`,writestheauditrecords,andrefusesaperson'sbareIDtokenunderacodingharnessname.WhatdependsonOktaistheappintegration,thegranttypesitsauthorizationserverallows,andtheportoftheloopbackredirect.Okta'sdocumentationreadsasmatchingthatportexactly,whichnobodyhasyetconfirmedagainstarealOktaorg,sothispagefixesoneport.##CreatetheappIntheOktaAdminConsole,openApplications,thenApplications,andpress**CreateAppIntegration**.Pick**OIDC-OpenIDConnect**and**NativeApplication**,thenpress**Next**.1.Nameit`Straza`.2.Under**Granttype**,tick**AuthorizationCode**.Tick**DeviceAuthorization**aswellonlywhenpeoplesigninwithacode,asalaterstepexplains.3.Enter`http://127.0.0.1:8765/callback`under**Sign-inredirectURIs**,withtheportyoupicked.4.Pick**Limitaccesstoselectedgroups**under**Assignments**,andnamethegroupswhosemembersuseStraza.5.Press**Save**.Ontheapp's**General**tab,keep**Clientauthentication**at**None**and**RequirePKCEasadditionalverification**ticked.Straza'sprogramsrunonpeople'smachinesandholdnosecret,andtheysendanS256challengewitheverybrowsersign-in.The**ClientID**onthesametabiswhatstrazadneedsas`oidc.clientId`.##AllowthegrantsattheauthorizationserverOpenSecurity,thenAPI,picktheauthorizationserveryousigninat,andopen**AccessPolicies**.MakesureapolicyassignedtotheStrazaapphasarulethatallows**AuthorizationCode**forthepeoplewhouseStraza.OktathenmintsIDtokensfortheStrazaappfromthatserver,andits**Settings**tabshowsthe**Issuer**thatstrazadneeds.##AddtheconsoleaddressTheconsoleandtheself-servicepagesigninwithinthebrowsertab,andOktasendsthetabbacktotheaddresspeopleopentheconsoleat,normallyyourstrazadpublicURL,followedby`/console/signin`.Becausethetabbuildsthataddressfromitsownorigin,aserverthatpeopleopenundertwoaddressesneedsboth.OntheStrazaapp's**General**tab,addthataddressunder**Sign-inredirectURIs**,suchas`https://straza.example.com/console/signin`,nexttotheloopbackredirect,andsave.Addoneaddressforeachaddresspeopleopentheconsoleat,oneachStrazaserver.ThetabthenredeemsthecodeatOktafromthepage,soOktamusttrusttheconsole'sorigin.OpenSecurity,thenAPI,then**TrustedOrigins**,andpress**AddOrigin**.Entertheoriginpeopleopentheconsoleat,suchas`https://straza.example.com`,tick**CORS**,andsave.Addoneoriginforeachsuchaddress.##PointstrazadatOktaThe`oidc`blockofstrazad'sconfigurationnamestheauthorizationserver'sissuer,theapp'sclientidandtheport.Putyourownissuerandclientidinplaceofthetwonamesinanglebrackets.ForOkta'sdefaultcustomauthorizationservertheissuerhastheform`https://<your-org>.okta.com/oauth2/default`.```yamloidc:issuer:<issuer-of-your-authorization-server>clientId:<client-id-of-the-straza-app>loopbackPort:8765jitProvision:false```Writetheissuerexactlyastheauthorizationservershowsit,becauseitmustequaltheissuerinOkta'sIDtokens.strazadreadsthediscoverydocumenttherewhenitstartsandrefusestostartwhenitcannotreachit.Restartstrazadafterthechange.Oktadocuments`auth_time`amongtheclaimsofitsIDtokens,andStrazaneedsthatclaimtoacceptabrowsersign-inforamachine.Okta'sdocumentationreadsasacceptingaloopbackredirectonlywiththeexactportithasregistered,whichisnotyetconfirmedagainstarealOktaorg,so`oidc.loopbackPort`,or`STRAZA_OIDC_LOOPBACK_PORT`,carriesthesameportastheapp'ssign-inredirect.strazadpublishesitin`/.well-known/straza/idp.json`,and`strazaservice`thenlistensthereon127.0.0.1fortheoneanswerofeachsign-in.Pickaportnootherprogramonpeople'smachinesuses,becauseasign-inthatfindsittakenstopswiththesentencebelow.Ifthisfails:``Strazacouldnotwaitforthesign-inansweronport8765,becauseanotherprogramusesit.Waitaminuteandrun`strazaenroll`again,oraskyourStrazaadmintochangeoidc.loopbackPort.``:Anotherprogramonthemachineholdstheport,oftenasign-inthatstillwaits.Waitforit,orchangetheportatOktaandin`oidc.loopbackPort`together.##Allowsign-inwithacodeSkipthisstepunlesspeopleneedit.Amachinewithnodisplayenrollswith`strazaenroll--use-device-code`,whichneedsthe**DeviceAuthorization**granttypetickedontheappandallowedintheaccesspolicyruleofyourauthorizationserver.Amachineenrolledwithacodeisstillrefusedwhile`governance.minSignIn`is`browser`,theenterprisedefault.##Howatokenfindsitsaccount{.nostep}strazadfirstmatchestheIDtoken's`sub`totheaccount's`externalId`.WhenOktaalsoprovisionspeopleoverSCIMwiththeOktauseridas`externalId`,as[Okta](https://docs.straza.ai/guides/connect-identity/okta/index.md)mapsit,thatidisthe`sub`ofOkta'sIDtokens,andeverysign-infindsitsaccount.Withoutamatch,thefirstsign-inlinksanaccountthathasno`externalId`yetbymatching`preferred_username`toits`userName`.##SigninOnaperson'smachine,inadesktopsession,enrollthemachine.Terminal,ontheperson'smachine:```shstrazaenroll--serverhttps://straza.example.com```Enrollnamesyourauthorizationserverinalinethatstarts`Signinginatyouridentityprovider:`,thenopensthebrowseratOkta'ssign-inpage.Oktaasksthepersontosigninagain,withthefactorsyoursign-onpolicyrequires,becauseStrazaasksforafreshsign-in.Thebrowserthenreturnsto`strazaservice`onthemachine,attheportyoufixed.Youshouldsee:`Enrolledas`andtheperson'susername,then`TheStrazabackgroundserviceholdsthismachine'skey.`Intheconsole,**Signin**takesthetabtoOkta'ssign-inpageandbacktothepagethepersonstartedon.Theconsoledoesnotaskforafreshsign-in,soOktamaysendabrowserthatissignedintoOktastraightback.Ifthisfails:Oktashowsanerroraboutthe`redirect_uri`inthebrowser:Theapp'ssign-inredirectdoesnotmatchtheoneStrazasent.CheckthattheportatOktaequals`oidc.loopbackPort`,andthatthehostis127.0.0.1.Thecommandgivesupafter5minutes.Asentencethatstarts`Youridentityproviderrefusedthesign-inandsaid:`:Oktarefusedthesign-inandsentitsreason,whichthesentencequotes.Apersonoutsidetheassignedgroups,oranaccesspolicyrulewithoutthegrant,aretheusualcauses.`Thesign-indidnotcomebackfromyouridentityprovider.Ifitshowedanerroraboutaredirectaddress,youradministratormustaddhttps://straza.example.com/console/signintoStraza'sregistrationthere.PressSignintotryagain.`:Theconsolesaysthis,withyourserver'saddress,afterOktarefuseditsredirect.Addtheaddressunder**Sign-inredirectURIs**,astheconsoleaddressstepshows.Aconsolesentencethatstarts`Youridentityproviderat`andgoeson`didnotletthispagefinishthesign-in.`:Thebrowsercouldnotredeemthesign-inatOkta,becausetheserver'soriginisnotatrustedoriginwithCORS.Additunder**TrustedOrigins**.``Strazarefusedthissign-inbecausetheidentityprovidersentnoauth_timeclaim,soStrazacannottellthatyousignedinjustnow.AskITtoaddtheauth_timeclaimtotheIDtokenoftheStrazaapp,thenrun`strazaenroll`again.``:TheIDtokenlacks`auth_time`.Checktheclaimsoftheauthorizationserveryousigninat.##Caveats{.nostep}DeactivatingapersoninOktastopsnewsign-insandenrollments.Okta'sSCIMdeactivation,whenOktaprovisionsStraza,alsocutstheperson'srunningStrazasessionsandrefuseseverycheck-infromtheirmachinesuntilOktareactivatesthem.WhileOktacannotsignanyonein,thebreak-glassadminstillsignsinthrough**Emergencysign-in**ontheconsole'ssign-incard,whichopensStraza'sownsign-inpage,andmintsatokentherewhenstrazactlisneeded.##Next{.nostep}-[Enrollamachine](https://docs.straza.ai/guides/govern-an-agent/enroll-a-machine/index.md)walkstheenrollmentandeveryrefusalitcanmeet.-[Okta](https://docs.straza.ai/guides/connect-identity/okta/index.md)provisionspeopleandtheirrolemembershipfromOktaoverSCIM.-[EntraIDlogin](https://docs.straza.ai/guides/connect-identity/entra-login/index.md)setsupthesamesign-inatMicrosoftEntraID.


Walked on v1.0.0-1577-ged23b225-dirty on 2026-10-22, except every Okta step, which has not run against a real Okta org. Not walked. The Okta steps follow Okta's documentation as read on 2026-10-22, and the Straza side follows the code of the working tree of the browser sign-in before its commit. No step ran against an Okta org. The console address step and the console's sign-in were written from the code on 2026-10-22 and not walked.

