[{"data":1,"prerenderedAt":951},["ShallowReactive",2],{"navigation":3,"/docs/features/sso":146,"/docs/features/sso-surround":946},[4,23,83,93,108,123,131],{"title":5,"path":6,"stem":7,"children":8,"icon":22},"Getting Started","/docs/getting-started","docs/1.getting-started/1.index",[9,12,17],{"title":10,"path":6,"stem":7,"icon":11},"What is TaskView","i-lucide-house",{"title":13,"path":14,"stem":15,"icon":16},"Installation","/docs/getting-started/installation","docs/1.getting-started/2.installation","i-lucide-download",{"title":18,"path":19,"stem":20,"icon":21},"Quick Start","/docs/getting-started/usage","docs/1.getting-started/3.usage","i-lucide-rocket",false,{"title":24,"icon":22,"path":25,"stem":26,"children":27,"page":22},"Features","/docs/features","docs/2.features",[28,33,38,43,48,53,58,63,68,73,78],{"title":29,"path":30,"stem":31,"icon":32},"Projects and Lists","/docs/features/projects-and-lists","docs/2.features/1.projects-and-lists","i-lucide-folder",{"title":34,"path":35,"stem":36,"icon":37},"Organizations","/docs/features/organizations","docs/2.features/10.organizations","i-lucide-building-2",{"title":39,"path":40,"stem":41,"icon":42},"SSO (Single Sign-On)","/docs/features/sso","docs/2.features/11.sso","i-lucide-shield-check",{"title":44,"path":45,"stem":46,"icon":47},"Tasks","/docs/features/tasks","docs/2.features/2.tasks","i-lucide-check-square",{"title":49,"path":50,"stem":51,"icon":52},"Kanban Board","/docs/features/kanban","docs/2.features/3.kanban","i-lucide-columns-3",{"title":54,"path":55,"stem":56,"icon":57},"Dependency Graph","/docs/features/graph","docs/2.features/4.graph","i-lucide-git-branch",{"title":59,"path":60,"stem":61,"icon":62},"Dashboard","/docs/features/dashboard","docs/2.features/5.dashboard","i-lucide-layout-dashboard",{"title":64,"path":65,"stem":66,"icon":67},"Notifications","/docs/features/notifications","docs/2.features/6.notifications","i-lucide-bell",{"title":69,"path":70,"stem":71,"icon":72},"Webhooks","/docs/features/webhooks","docs/2.features/7.webhooks","i-lucide-webhook",{"title":74,"path":75,"stem":76,"icon":77},"API Tokens","/docs/features/api-tokens","docs/2.features/8.api-tokens","i-lucide-key-round",{"title":79,"path":80,"stem":81,"icon":82},"Sessions & Devices","/docs/features/sessions","docs/2.features/9.sessions","i-lucide-monitor-smartphone",{"title":84,"icon":22,"path":85,"stem":86,"children":87,"page":22},"Integrations","/docs/integrations","docs/3.integrations",[88],{"title":89,"path":90,"stem":91,"icon":92},"GitHub & GitLab Setup","/docs/integrations/setup","docs/3.integrations/1.setup","i-lucide-git-pull-request",{"title":94,"icon":22,"path":95,"stem":96,"children":97,"page":22},"Configuration","/docs/configuration","docs/4.configuration",[98,103],{"title":99,"path":100,"stem":101,"icon":102},"Environment Variables","/docs/configuration/environment-variables","docs/4.configuration/1.environment-variables","i-lucide-settings",{"title":104,"path":105,"stem":106,"icon":107},"Authentication","/docs/configuration/authentication","docs/4.configuration/2.authentication","i-lucide-lock",{"title":109,"icon":22,"path":110,"stem":111,"children":112,"page":22},"Collaboration","/docs/collaboration","docs/5.collaboration",[113,118],{"title":114,"path":115,"stem":116,"icon":117},"Team Members","/docs/collaboration/members","docs/5.collaboration/1.members","i-lucide-users",{"title":119,"path":120,"stem":121,"icon":122},"Roles and Permissions","/docs/collaboration/roles-and-permissions","docs/5.collaboration/2.roles-and-permissions","i-lucide-shield",{"title":124,"path":125,"stem":126,"children":127,"icon":22},"FAQ","/docs/faq","docs/6.faq/1.index",[128],{"title":129,"path":125,"stem":126,"icon":130},"Frequently Asked Questions","i-lucide-circle-help",{"title":132,"icon":22,"path":133,"stem":134,"children":135,"page":22},"Guides","/docs/guides","docs/7.guides",[136,141],{"title":137,"path":138,"stem":139,"icon":140},"Deploy TaskView on a VPS with Nginx","/docs/guides/deploy-vps-nginx","docs/7.guides/1.deploy-vps-nginx","i-lucide-server",{"title":142,"path":143,"stem":144,"icon":145},"TaskView for Freelancers","/docs/guides/taskview-for-freelancers","docs/7.guides/2.taskview-for-freelancers","i-lucide-briefcase",{"id":147,"title":39,"body":148,"description":940,"extension":941,"meta":942,"navigation":943,"path":40,"seo":944,"stem":41,"__hash__":945},"docs/docs/2.features/11.sso.md",{"type":149,"value":150,"toc":921},"minimark",[151,164,169,196,199,203,218,222,227,298,303,310,313,334,337,341,348,353,387,390,399,404,407,473,494,500,503,507,567,570,588,595,599,611,621,625,628,643,646,659,663,674,677,681,685,739,743,819,823,867,871,877,883,889,895,905,911,917],[152,153,154,155,159,160,163],"p",{},"SSO lets your organization's members sign in to TaskView using your corporate identity provider (IdP). Supported protocols: ",[156,157,158],"strong",{},"SAML 2.0"," and ",[156,161,162],{},"OpenID Connect (OIDC)",".",[165,166,168],"h2",{"id":167},"how-it-works","How it works",[170,171,172,176,184,187,190,193],"ol",{},[173,174,175],"li",{},"User enters their email on the TaskView login page (SSO tab)",[173,177,178,179,183],{},"TaskView looks up the email domain (e.g. ",[180,181,182],"code",{},"company.com",") and finds the matching SSO config",[173,185,186],{},"User gets redirected to your IdP (Okta, Azure AD, etc.)",[173,188,189],{},"User authenticates at the IdP",[173,191,192],{},"IdP redirects back to TaskView with identity proof",[173,194,195],{},"TaskView creates an account (if new) and logs the user in",[152,197,198],{},"Users who sign in via SSO are automatically added to the organization that owns the SSO config.",[165,200,202],{"id":201},"setting-up-sso","Setting up SSO",[152,204,205,206,209,210,213,214,217],{},"Go to your organization's settings → ",[156,207,208],{},"SSO"," tab. You need the ",[156,211,212],{},"admin"," or ",[156,215,216],{},"owner"," role.",[219,220,158],"h3",{"id":221},"saml-20",[152,223,224],{},[156,225,226],{},"Required fields:",[228,229,230,243],"table",{},[231,232,233],"thead",{},[234,235,236,240],"tr",{},[237,238,239],"th",{},"Field",[237,241,242],{},"Description",[244,245,246,255,266,274,282,290],"tbody",{},[234,247,248,252],{},[249,250,251],"td",{},"Provider name",[249,253,254],{},"Display name shown in the UI (e.g. \"Okta\", \"Azure AD\")",[234,256,257,260],{},[249,258,259],{},"Email domain",[249,261,262,263,265],{},"The domain used for routing (e.g. ",[180,264,182],{},"). One domain = one SSO config",[234,267,268,271],{},[249,269,270],{},"IdP SSO URL",[249,272,273],{},"Your IdP's SAML endpoint where login requests are sent",[234,275,276,279],{},[249,277,278],{},"SP Entity ID",[249,280,281],{},"TaskView's identifier. Can be any string, must match what you configure in your IdP",[234,283,284,287],{},[249,285,286],{},"IdP Certificate",[249,288,289],{},"Your IdP's public signing certificate (base64, without BEGIN/END headers)",[234,291,292,295],{},[249,293,294],{},"ACS URL (Callback)",[249,296,297],{},"The URL where your IdP sends SAML responses. Shown after creating the config - copy it to your IdP",[152,299,300],{},[156,301,302],{},"Using Metadata URL (recommended):",[152,304,305,306,309],{},"Instead of filling fields manually, paste your IdP's metadata URL and click ",[156,307,308],{},"Sync",". This auto-fills the IdP SSO URL, Certificate, and Logout URL from the metadata XML.",[152,311,312],{},"Example metadata URLs:",[314,315,316,322,328],"ul",{},[173,317,318,319],{},"Okta: ",[180,320,321],{},"https://your-org.okta.com/app/xxx/sso/saml/metadata",[173,323,324,325],{},"Azure AD: ",[180,326,327],{},"https://login.microsoftonline.com/{tenant}/federationmetadata/2007-06/federationmetadata.xml",[173,329,330,331],{},"Keycloak: ",[180,332,333],{},"http://your-keycloak/realms/{realm}/protocol/saml/descriptor",[152,335,336],{},"SP Entity ID is not filled from metadata - you set it yourself. It must match between TaskView and your IdP.",[219,338,340],{"id":339},"saml-signature-requirements","SAML signature requirements",[152,342,343,344,347],{},"TaskView ",[156,345,346],{},"requires"," that your IdP signs SAML Assertions. Without a valid signature, authentication will be rejected.",[152,349,350],{},[156,351,352],{},"IdP configuration:",[228,354,355,365],{},[231,356,357],{},[234,358,359,362],{},[237,360,361],{},"Setting",[237,363,364],{},"Required value",[244,366,367,378],{},[234,368,369,372],{},[249,370,371],{},"Sign assertions",[249,373,374,377],{},[156,375,376],{},"ON"," (required)",[234,379,380,383],{},[249,381,382],{},"Sign documents (response)",[249,384,385,377],{},[156,386,376],{},[152,388,389],{},"TaskView validates the assertion signature. The document (response) signature provides additional transport-level integrity. Both should be enabled for maximum security.",[391,392,393],"blockquote",{},[152,394,395,398],{},[156,396,397],{},"Note:"," If you encounter \"Invalid signature\" errors with both signatures enabled, verify that your IdP certificate is correct. Re-sync from metadata URL if needed.",[152,400,401],{},[156,402,403],{},"Request signing (enterprise, optional):",[152,405,406],{},"For environments that require signed AuthnRequests, you can provide an SP signing key pair. Generate it with:",[408,409,414],"pre",{"className":410,"code":411,"language":412,"meta":413,"style":413},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","openssl req -x509 -newkey rsa:2048 -keyout sp-key.pem -out sp-cert.pem -days 3650 -nodes -subj \"/CN=taskview\"\n","bash","",[180,415,416],{"__ignoreMap":413},[417,418,421,425,429,432,435,438,441,444,447,450,453,457,460,463,467,470],"span",{"class":419,"line":420},"line",1,[417,422,424],{"class":423},"sBMFI","openssl",[417,426,428],{"class":427},"sfazB"," req",[417,430,431],{"class":427}," -x509",[417,433,434],{"class":427}," -newkey",[417,436,437],{"class":427}," rsa:2048",[417,439,440],{"class":427}," -keyout",[417,442,443],{"class":427}," sp-key.pem",[417,445,446],{"class":427}," -out",[417,448,449],{"class":427}," sp-cert.pem",[417,451,452],{"class":427}," -days",[417,454,456],{"class":455},"sbssI"," 3650",[417,458,459],{"class":427}," -nodes",[417,461,462],{"class":427}," -subj",[417,464,466],{"class":465},"sMK4o"," \"",[417,468,469],{"class":427},"/CN=taskview",[417,471,472],{"class":465},"\"\n",[152,474,475,476,479,480,159,483,486,487,490,491,493],{},"Paste ",[180,477,478],{},"sp-key.pem"," contents into ",[156,481,482],{},"SP Private Key",[180,484,485],{},"sp-cert.pem"," into ",[156,488,489],{},"SP Certificate"," in TaskView. Upload ",[180,492,485],{}," to your IdP so it can verify the signature.",[152,495,496,497,163],{},"When signing keys are provided, TaskView signs AuthnRequests with ",[156,498,499],{},"RSA-SHA256",[219,501,162],{"id":502},"openid-connect-oidc",[152,504,505],{},[156,506,226],{},[228,508,509,517],{},[231,510,511],{},[234,512,513,515],{},[237,514,239],{},[237,516,242],{},[244,518,519,526,535,543,551,559],{},[234,520,521,523],{},[249,522,251],{},[249,524,525],{},"Display name (e.g. \"Google Workspace\", \"Keycloak OIDC\")",[234,527,528,530],{},[249,529,259],{},[249,531,262,532,534],{},[180,533,182],{},")",[234,536,537,540],{},[249,538,539],{},"Issuer URL",[249,541,542],{},"Your IdP's OIDC issuer URL. Used for auto-discovery of endpoints",[234,544,545,548],{},[249,546,547],{},"Client ID",[249,549,550],{},"OAuth client ID from your IdP",[234,552,553,556],{},[249,554,555],{},"Client Secret",[249,557,558],{},"OAuth client secret from your IdP",[234,560,561,564],{},[249,562,563],{},"Callback URL",[249,565,566],{},"The URL where your IdP redirects after authentication. Shown after creating the config",[152,568,569],{},"Example issuer URLs:",[314,571,572,578,583],{},[173,573,574,575],{},"Google: ",[180,576,577],{},"https://accounts.google.com",[173,579,324,580],{},[180,581,582],{},"https://login.microsoftonline.com/{tenant}/v2.0",[173,584,330,585],{},[180,586,587],{},"http://your-keycloak/realms/{realm}",[152,589,590,591,594],{},"TaskView uses ",[156,592,593],{},"PKCE (S256)"," for the authorization code exchange. Your IdP must support the authorization code grant with PKCE.",[165,596,598],{"id":597},"email-domain-routing","Email domain routing",[600,601,604],"callout",{"color":602,"icon":603},"warning","i-lucide-alert-triangle",[152,605,606,607,610],{},"Each SSO config is bound to an ",[156,608,609],{},"email domain",". One domain can only have one SSO config - this is enforced at the database level.",[152,612,613,614,617,618,620],{},"When a user enters ",[180,615,616],{},"alice@company.com"," on the SSO login tab, TaskView checks if domain ",[180,619,182],{}," has a configured SSO provider. If yes - redirect to IdP. If no - show an error.",[165,622,624],{"id":623},"user-provisioning","User provisioning",[152,626,627],{},"When a user authenticates via SSO for the first time:",[170,629,630,633,636],{},[173,631,632],{},"A TaskView account is created automatically (with a random password - they'll only use SSO)",[173,634,635],{},"A personal workspace is created for them",[173,637,638,639,642],{},"They are added to the SSO config's organization with the ",[156,640,641],{},"member"," role",[152,644,645],{},"For existing users (already registered with the same email), SSO login links their account - no new account is created, data is preserved.",[600,647,650,656],{"color":648,"icon":649},"info","i-lucide-info",[152,651,652,655],{},[156,653,654],{},"Removing users from the organization:"," If you remove a user from the organization in TaskView but do not deactivate their account in the identity provider (IdP), the user will be automatically re-added to the organization on their next SSO login. This is standard JIT (Just-In-Time) provisioning behavior — the IdP is the source of truth for access.",[152,657,658],{},"To fully block a user's access, deactivate or delete their account in the IdP. If SCIM provisioning is enabled, deactivating the user via SCIM will remove them from both the IdP and TaskView.",[165,660,662],{"id":661},"replay-attack-protection-saml","Replay attack protection (SAML)",[152,664,665,666,669,670,673],{},"TaskView stores SAML AuthnRequest IDs in a PostgreSQL table (",[180,667,668],{},"saml_request_cache",") and validates the ",[180,671,672],{},"InResponseTo"," field in SAML responses. Each request ID can only be used once. This prevents replay attacks even in multi-instance deployments behind a load balancer.",[152,675,676],{},"Request IDs expire after 5 minutes.",[165,678,680],{"id":679},"api-endpoints","API endpoints",[219,682,684],{"id":683},"public","Public",[228,686,687,699],{},[231,688,689],{},[234,690,691,694,697],{},[237,692,693],{},"Method",[237,695,696],{},"URL",[237,698,242],{},[244,700,701,714,726],{},[234,702,703,706,711],{},[249,704,705],{},"GET",[249,707,708],{},[180,709,710],{},"/module/sso/providers?domain={domain}",[249,712,713],{},"Check if SSO is configured for a domain",[234,715,716,718,723],{},[249,717,705],{},[249,719,720],{},[180,721,722],{},"/module/sso/login/{configId}",[249,724,725],{},"Initiate SSO login (redirects to IdP)",[234,727,728,731,736],{},[249,729,730],{},"GET/POST",[249,732,733],{},[180,734,735],{},"/module/sso/callback/{configId}",[249,737,738],{},"Handle IdP callback",[219,740,742],{"id":741},"admin-requires-authentication-org-admin-role","Admin (requires authentication + org admin role)",[228,744,745,755],{},[231,746,747],{},[234,748,749,751,753],{},[237,750,693],{},[237,752,696],{},[237,754,242],{},[244,756,757,769,781,794,807],{},[234,758,759,761,766],{},[249,760,705],{},[249,762,763],{},[180,764,765],{},"/module/sso/admin/metadata?url={metadataUrl}",[249,767,768],{},"Parse SAML metadata XML from URL",[234,770,771,773,778],{},[249,772,705],{},[249,774,775],{},[180,776,777],{},"/module/sso/admin/configs?organizationId={id}",[249,779,780],{},"List SSO configs for an organization",[234,782,783,786,791],{},[249,784,785],{},"POST",[249,787,788],{},[180,789,790],{},"/module/sso/admin/configs",[249,792,793],{},"Create SSO config",[234,795,796,799,804],{},[249,797,798],{},"PATCH",[249,800,801],{},[180,802,803],{},"/module/sso/admin/configs/{configId}",[249,805,806],{},"Update SSO config",[234,808,809,812,816],{},[249,810,811],{},"DELETE",[249,813,814],{},[180,815,803],{},[249,817,818],{},"Delete SSO config",[165,820,822],{"id":821},"database-tables","Database tables",[228,824,825,835],{},[231,826,827],{},[234,828,829,832],{},[237,830,831],{},"Table",[237,833,834],{},"Purpose",[244,836,837,847,857],{},[234,838,839,844],{},[249,840,841],{},[180,842,843],{},"tv_auth.sso_configs",[249,845,846],{},"SSO provider configurations (SAML/OIDC settings per organization)",[234,848,849,854],{},[249,850,851],{},[180,852,853],{},"tv_auth.sso_identities",[249,855,856],{},"Links between TaskView users and their external SSO identities",[234,858,859,864],{},[249,860,861],{},[180,862,863],{},"tv_auth.saml_request_cache",[249,865,866],{},"SAML request ID cache for replay attack prevention",[165,868,870],{"id":869},"troubleshooting","Troubleshooting",[152,872,873,876],{},[156,874,875],{},"\"SSO not configured\" when entering email"," - No SSO config exists for this email domain. Create one in organization settings.",[152,878,879,882],{},[156,880,881],{},"\"Invalid requester\" (SAML)"," - SP Entity ID in TaskView doesn't match Client ID in your IdP. They must be identical.",[152,884,885,888],{},[156,886,887],{},"\"Invalid signature\" (SAML)"," - IdP Certificate in TaskView is wrong or outdated. Re-sync from metadata URL or copy the certificate from your IdP's metadata XML.",[152,890,891,894],{},[156,892,893],{},"\"Invalid document signature\" (SAML)"," - The document (response) signature validation failed. Verify the IdP certificate is correct and re-sync from metadata URL.",[152,896,897,900,901,904],{},[156,898,899],{},"\"Failed to initiate SSO login\" (OIDC)"," - Issuer URL is wrong, or the IdP is unreachable. Verify the URL by opening ",[180,902,903],{},"{issuer}/.well-known/openid-configuration"," in a browser.",[152,906,907,910],{},[156,908,909],{},"\"Invalid parameter: redirect_uri\" (OIDC)"," - Callback URL in TaskView doesn't match \"Valid redirect URIs\" in your IdP. Copy the callback URL from TaskView's SSO settings and add it to your IdP.",[152,912,913,916],{},[156,914,915],{},"User logged in as wrong person"," - The IdP has an active session for another user. This is normal SSO behavior - the IdP controls sessions, not TaskView. Use a different browser or incognito window to test with a different user.",[918,919,920],"style",{},"html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":413,"searchDepth":922,"depth":922,"links":923},2,[924,925,931,932,933,934,938,939],{"id":167,"depth":922,"text":168},{"id":201,"depth":922,"text":202,"children":926},[927,929,930],{"id":221,"depth":928,"text":158},3,{"id":339,"depth":928,"text":340},{"id":502,"depth":928,"text":162},{"id":597,"depth":922,"text":598},{"id":623,"depth":922,"text":624},{"id":661,"depth":922,"text":662},{"id":679,"depth":922,"text":680,"children":935},[936,937],{"id":683,"depth":928,"text":684},{"id":741,"depth":928,"text":742},{"id":821,"depth":922,"text":822},{"id":869,"depth":922,"text":870},"Configure SAML 2.0 or OpenID Connect SSO for your organization. Users authenticate through your corporate identity provider (Okta, Azure AD, Google Workspace, Keycloak) and get automatic access to TaskView.","md",{},{"icon":42},{"title":39,"description":940},"pysKxFgDQdPNPVpqG1Q6LpiL5vficLhMRgzQuddVjV8",[947,949],{"title":34,"path":35,"stem":36,"description":948,"icon":37,"children":-1},"Group projects and team members under organizations in TaskView. Manage access with organization-level roles - owner, admin, and member. Each organization has its own members, projects, and settings.",{"title":44,"path":45,"stem":46,"description":950,"icon":47,"children":-1},"Create and manage tasks in TaskView - subtasks, deadlines, priorities, assignees, tags, rich-text notes, financial tracking, and full change history with restore. Self-hosted task tracking with no limits.",1776501816761]