{"id":19317755,"url":"https://github.com/queeniecplusplus/iap","last_synced_at":"2026-06-09T20:31:23.536Z","repository":{"id":104588278,"uuid":"310955662","full_name":"QueenieCplusplus/IAP","owner":"QueenieCplusplus","description":"Identify Aware Proxy","archived":false,"fork":false,"pushed_at":"2020-11-18T03:16:49.000Z","size":930,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-02-24T04:44:52.172Z","etag":null,"topics":["idp","idp-login","proxy","proxy-configuration","proxy-re-encryption","proxypool"],"latest_commit_sha":null,"homepage":"https://github.com/QueenieCplusplus/QuickGoThru/blob/master/README.md#iap-security","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/QueenieCplusplus.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-11-08T00:14:15.000Z","updated_at":"2021-05-21T02:27:25.000Z","dependencies_parsed_at":null,"dependency_job_id":"8243e580-7cb1-46da-9f3b-416b7d1c1889","html_url":"https://github.com/QueenieCplusplus/IAP","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/QueenieCplusplus/IAP","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueenieCplusplus%2FIAP","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueenieCplusplus%2FIAP/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueenieCplusplus%2FIAP/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueenieCplusplus%2FIAP/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/QueenieCplusplus","download_url":"https://codeload.github.com/QueenieCplusplus/IAP/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/QueenieCplusplus%2FIAP/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34125332,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["idp","idp-login","proxy","proxy-configuration","proxy-re-encryption","proxypool"],"created_at":"2024-11-10T01:16:09.220Z","updated_at":"2026-06-09T20:31:23.510Z","avatar_url":"https://github.com/QueenieCplusplus.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# IAP\n\n* use Identify Aware Proxy to restrict access to web app.\n\n* IAP provides user id info to admin.\n\n* IAP got feautre of Cypto to against Spoofing.\n\n![](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/iap.png)\n\n# Core Steps:\n\n(1) deploy a simple (python) web page\n\n(2) enable IAP service to restrice access to app\n\n(3) get users id info from IAP\n\n(4) avoid from spoofing using Crypto-Verification\n\n# Main Cmd line\n\n    gcloud app deploy\n    \n    gcloud app browse\n\n---------\n\n# GAE (most simplest deployment solution)\n\nprework: study how to make app wrapped in GAE using yaml file.\n\nstep from 1\n\n\u003e Deployment using AGE\n\n* 1.1, in cloud console, open the cloud shell tab, and type follwing cmd line to clone app from github.\n\n      git clone https://github.com/QueenieCplusplus/Login_Python_App.git\n      \n      cd Login_Python_App\n      \n      cat [file name]\n      // to do edit or read the code line\n      \n* tips \u0026 attentions:\n\nthe main code is in main.py file, it use framework called flask, which responds requests with contents of template.\n\n1. the template file is in templates/index.html, which shows a plain HTML.\n2. the other template is in templates/privacy.html, which contains privacy policy.\n3. requirements.txt lists all the libs that app uses.\n4. app.yaml file tells GCP this app is wrapped in GAE.\n\n* 1.2, deploy GAE\n\n      gcloud app deploy\n      \n* 1.3, select the nearest region for App and type Y.\n\n* 1.4, see result after deployment.\n\n      gcloud app browse\n      \n      [result]\n      \n    ![](https://cdn.qwiklabs.com/BUrEJObysrNmE%2FqmU234RAj3kMiAvwOswH%2FAmSdJ%2FNY%3D)\n\n# IAP\n\nfrom step 2:\n\n\u003e restrict access using IAP\n\n* 2.1, in cloud console, navigate to Secuity \u003e IAP\n\n* 2.2, enable the IAP service, then click on the tab \"configure consent screen\" for Oauth.\n\n* 2.3, select \"internal\" for user type, and click on \"create\".\n\n* 2.4, config the property of the Oauth.\n\n ![](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/oauth_val.png)\n\n* 2.5, in cloud shell, disable the flexible api.\n\n      gcloud services disable appengineflex.googleapis.com (optional)\n      \n* tips \u0026 attentions:\n\n    App Engine has its standard and flexible environments which are optimized for different application architectures. Currently, when enabling IAP for App Engine, if the Flex API is enabled, GCP will look for a Flex Service Account. Your project comes with a multitude of APIs already enabled for the purpose of convenience. However, this creates a unique situation where the Flex API is enabled without a Service Account created.\n    \n* 2.6, return to IAP config page in cloud console, and refresh it to see blow GAE row, and select toggle button to enable the IAP service in column.the domain is procted then.\n\n ![](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/protect%20http%20resources.png)\n\n# Login Test\n\n* 2.7, before telling IAP which account is allowed through,\nthe login deose not work out.\n\n![](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/login%20test.png)\n\n# AC\n\nAccess Control\n\n* 2.8, back to IAP config page in cloud console, and set up the AC list.\n\n![ac0](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/AC1.png)\n\n![ac1](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/AC1-2.png)\n\n# AC Test\n\nLogin Again without Cache\n\n* 2.9, browse to app url, refresh it, ang test login using the following adress.\n\n     https://iap-example-999999.appspot.com/_gcp_iap/clear_login_cookie.\n     \n* 2.10, do not enter the already-exist account, use \"another user account\", re-enter username and password to check credentials is allowed.\n\n# Spoofing bypass IAP\n\nspoofer might attack website by bypassing the IAP, and turn off the IAP.\n\nfrom step 3:\n\n\u003e User ID will shows in request header it passed thru in web browser.\nMake an app page to display it.\n\n* 3.1, back to cloud shell, type cm line below.\n\n      git clone https://github.com/googlecodelabs/user-authentication-with-iap.git\n      \n      cd user-authentication-with-ia\n      \n      cd 2-HelloUser\n        \n* 3.2,  deploy it with GAE.\n\n      gcloud app deploy\n      \n* tips \u0026 attentions:\n\nvesrion 2 program has been changed to retrieve the user information that IAP provides in request headers, and the template now displays that data. X-Goog-Authenticated-User- headers are provided by IAP.\n\n        // in main.py in 2-HelloUser\n        user_email = request.headers.get('X-Goog-Authenticated-User-Email')\n        user_id = request.headers.get('X-Goog-Authenticated-User-ID')\n        \n        // render template\n        page = render_template('index.html', email=user_email, id=user_id)\n        \n        // index.html in 2-HellowUser\n        Hello, {{ email }}! Your persistent ID is {{ id }}.\n        \n        // template\n        \n        \u003c!doctype html\u003e\n        \u003chtml\u003e\n        \u003chead\u003e\n          \u003ctitle\u003eIAP Hello User\u003c/title\u003e\n        \u003c/head\u003e\n        \u003cbody\u003e\n          \u003ch1\u003eHello World\u003c/h1\u003e\n\n          \u003cp\u003e\n            Hello, totally fake email! Your persistent ID is None.\n          \u003c/p\u003e\n\n          \u003cp\u003e\n            This is step 2 of the \u003cem\u003eUser Authentication with IAP\u003c/em\u003e\n            codelab.\n         \u003c/p\u003e\n\n        \u003c/body\u003e\n        \u003c/html\u003e\n\n* 3.3, run gae browse\n\n      gcloud app browse\n\n      [result in browse]\n      \n * 3.4, Hacker start to spoof.\n \n       curl -X GET \u003capps url\u003e -H \"X-Goog-Authenticated-User-Email: totally fake email\"\n\n![](https://raw.githubusercontent.com/QueenieCplusplus/IAP/main/gae%20browse.png)\n\n# Oauth\n\n\"make sure the IAP sevice is opened by admin\" \u0026 \"make sure developer is code with jwt lib for login\"\n\nIf there is a risk of IAP being turned off or bypassed, your app can check to make sure the id info it receives is valid. \n\nThis uses a web request header added by IAP, called X-Goog-IAP-JWT-Assertion. The value of the header is a crypto-signed object that also contains the user id data. Your app can verify the digital signature and use the data provided in this object to be certain that it was provided by IAP without alteration.\n\nDigital signature verification requires several extra steps, such as retrieving the latest set of Google public keys. You can decide whether your app needs these extra steps based on the risk that someone might be able to turn off or bypass IAP, and the sensitivity of the application.\n\nIf IAP is turned off or bypassed, the verified data would either be missing, or invalid, since it cannot have a valid signature unless it was created by the holder of Google's private keys.\n\n# Crypto\n\nfrom step 4:\n\n\u003e a protection to avoid http header spoofing\n\n* 4.1, in cloud shell, deploy version 3 app\n\n      git clone https://github.com/QueenieCplusplus/Login_Python_App.git\n      \n      cd Login_Python_App\n      \n      gcloud app deploy\n      \n      gcloud app browse\n      \n* tips \u0026 attentions:\n\nThe assertion is the cryptographically signed data provided in the specified request header. \n\nThe code uses jwt lib to validate and decode that data. \n\nValidation uses the \"public keys\" that Google provides for checking data it signs, and knowing the audience that the data was prepared for (essentially, the Google Cloud project that is being protected). Helper functions keys() and audience() gather and return those values.\n\nThe signed object has two pieces of data we need: the verified email address, and the unique ID value (provided in the sub, for subscriber, standard field).\n\n   code is like this:\n   \n       def user():\n       \n        assertion = request.headers.get('X-Goog-IAP-JWT-Assertion')\n        if assertion is None:\n            return None, None\n\n        info = jwt.decode(\n            assertion,\n            keys(), // provided by google\n            algorithms=['ES256'],\n            audience=audience() // provided by google\n        )\n\n        return info['email'], info['sub']\n        \n# Ref Doc\n\n  https://cloud.google.com/armor/docs/security-policy-overview\n  \n  https://cloud.google.com/armor/docs/configure-security-policies\n\n# Ref code\n\n5562\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueeniecplusplus%2Fiap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqueeniecplusplus%2Fiap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqueeniecplusplus%2Fiap/lists"}