Skip to content
Insights · Engineering

Which app did that install grant?

Name the app that install granted: installation id, app id, and permission. Another organization does not list this install.

Scroll
EngineeringOct 30, 202612 min readBy Salman Naqvi, Founder & CEO
Which app did that install grant?

A client says the automation can see the repository, or says it cannot. Tonight, three proofs, in an organization the agency or the client can open. Name the app that install granted: the installation id, the app id, and the permission on the resource you were asked about. If the installation is suspended, write that, including a suspended time, and do not invent a permission to fill the hole. Show a different installation whose account login, or whose repository selection, is not this one. Show another client's organization that does not list this installation. If any of the three needs the person who clicked install and then left, you have not named the app. You have a marketplace slide and a guess.

This is the installation of one app. It is not the branch a pull targeted. Which branch did that pull target? is the base ref and the head ref. A pull can target a branch the app cannot read, and an app can hold contents read while no pull is open. It is not the label on an issue. Which label did that issue carry? is a name and a color on an issue. A label is not a permission. It is not the phase a subscription schedule entered. Which phase did that schedule enter? is a schedule id and two dates. A phase is not an app id. It is not the voice a speech request used. A voice name is not a permission of write or read.

None of what follows is a rate for this engagement, and none of it is legal advice. The objects below are GitHub's current samples of an installation, of an organization installation, and of an installation request. The counts below that are a 2024 paper about the GitHub Marketplace, which is a catalog, not the installation on the organization you opened tonight. A count of other people's apps cannot name the permission on this install.

The list-installations sample and the get-installation sample print the same object, and that object does not agree with itself. The id is 1. account.login is octocat. account.id is 1. account.type is User. 4 characters. app_id is 1. target_id is 1. target_type is Organization. 12 characters. User is not Organization. Four fields print 1, and they are not one field. html_url on that sample points at organizations/github/settings/installations/1. The path says github. The account login says octocat. github is not octocat. repository_selection is selected. 8 characters. permissions are three: checks write, metadata read, and contents read. 3 keys. events are push and pull_request. 2 names. single_file_name is config.yaml. 11 characters. has_multiple_single_files is true. single_file_paths are config.yml and .github/issue_TEMPLATE.md. config.yml is 10 characters. The template path is 25. config.yaml is not config.yml. A true flag for multiple files does not make the single name match either path. created_at and updated_at are both 2017-07-08T16:18:44-04:00. The gap between them is 0. app_slug is github-actions. 14 characters. suspended_at is null. suspended_by is null. The get response is that same shape without the array. Same id is not a second installation (GitHub, List installations for the authenticated app).

The organization-installation sample prints id 1 again and is not that object. account.login is github. account.type is Organization, which matches target_type and does not match the list sample's User. account.id is 1 again. The account node_id decodes to 012:Organization1, which matches account id 1. repository_selection is all. 3 characters. all is not selected. client_id is Iv1.ab1112223334445c. 20 characters. The list sample does not include client_id at all. permissions are the same three keys. events are the same two names. single_file_name is config.yml. 10 characters. That matches one of the list sample's paths and does not match the list sample's single_file_name. created_at and updated_at are both 2018-02-09T20:51:14Z. Against the list sample's 2017-07-08T16:18:44-04:00, the gap is 18664350 seconds. 216 times 86400 is 18662400, and the remainder is 1950 seconds, which is 32 minutes and 30 seconds. The gap is 216 days, 0 hours, 32 minutes, and 30 seconds. Two examples that both print id 1 are not one install on the client's organization (GitHub, Get an organization installation for the authenticated app).

The installation request is a third sample, and its id is not an installation id. The request id is 25381. 5 characters, and not 1. The node_id decodes to 012:Integration1234567890. 1234567890 is not 25381. 1234567890 minus 25381 is 1234542509. The page does not print that subtraction. The account login is octo-org. 8 characters. account.id is 6811672. The account node_id decodes to 012:Organization6811672, which matches 6811672 and does not match the request id. requester.id is 1, and the requester node_id decodes to 04:User1, which matches requester id 1 and is the octocat user, not octo-org. type on the account is Organization. type on the requester is User. created_at is 2022-07-08T16:18:44-04:00. The clock time matches the list sample's 16:18:44-04:00, and the date does not. From 2017-07-08 to 2022-07-08 at that same clock is 157766400 seconds, which is 1826 days exactly. 5 times 365 is 1825. 1826 is not 1825. The page does not print 1826. The request object in that sample has no permissions map. Do not copy checks write onto a request that did not store it.

The authenticated-app sample is the app, and it is not the installation either. id is 1. slug is octoapp. 7 characters. name is Octocat App. 11 characters, counting the space. client_id is the same Iv1.ab1112223334445c. 20 characters. The node_id decodes to 011:Integration1, which matches app id 1. That match is the opposite of the request, whose node_id does not match 25381. description is an empty string. permissions are four: metadata read, contents read, issues write, and single_file write. 4 keys. The installation's three keys include checks and do not include issues or single_file. 4 is not 3. events are still push and pull_request. created_at is 2017-07-08T16:18:44-04:00, the same stamp as the list installation, on a different object. An app definition is not the grant on a client account (GitHub, Get the authenticated app).

The access-token sample is a fourth object, and it expired before the installation example was created. expires_at is 2016-07-11T22:14:10Z. The list installation's created_at is 2017-07-08T16:18:44-04:00. The gap is 31269874 seconds. 361 times 86400 is 31190400, and the remainder is 79474. 22 times 3600 is 79200. The remainder is 274 seconds, which is 4 minutes and 34 seconds. The gap is 361 days, 22 hours, 4 minutes, and 34 seconds. A token whose sample expiry is earlier than the sample installation is not the token for that installation. The sample token string is 40 characters and begins with ghs_. The page prints the whole example. It is an example. permissions on the token are issues write and contents read. 2 keys. 2 is not the installation's 3, and issues is not checks. repository_selection is selected, which matches the list installation and does not match the organization sample's all. The repository in that sample has id 1296269. name is Hello-World. 11 characters. The description on that repository is This your first repo! 21 characters. The sentence is missing a word the page does not supply. Do not repair it. A repository id is not an installation id.

The study people reach for when they want a count of GitHub apps is a catalog, and a catalog is not an installation. SK Golam Saroar, Waseefa Ahmed, Elmira Onagh, and Maleknaz Nayebi, at York University, examine the GitHub Marketplace. They report 8,318 automated production tools, 440 Apps and 7,878 Actions, across 32 categories. 440 plus 7,878 is 8,318. That addition matches. 8,318 divided by 32 is 259.9375, not an integer. The page does not print 259.9375, and it does not claim the categories are even. They also mapped 515 research papers from an original 11,741. The figure's steps are 11,741, 11,539, 9,023, 1,441, 1,169, 537, and 515. 11,741 minus 11,539 is 202. 11,539 minus 9,023 is 2,516. 9,023 minus 1,441 is 7,582. 1,441 minus 1,169 is 272. 1,169 minus 537 is 632. 537 minus 515 is 22. The prose says 515 from the original 11,741 and does not print those six gaps. 11,741 minus 515 is 11,226. The page does not print 11,226 (Saroar, Ahmed, Onagh, and Nayebi, GitHub Marketplace for Automation and Innovation in Software Production).

The same paper's later counts do not all describe the same set of apps. They scraped attributes from 439 of 440 Apps and from 7,846 of 7,878 Actions. 440 minus 439 is 1. 7,878 minus 7,846 is 32. 32 is also the category count. The sentence does not say the missing actions are the categories. 1 is not 32. 18.64% of the Apps, 82 of 440, have a short description under 40 characters. 82 divided by 440 is 0.1863636, which is 18.636%. They print 18.64%. 18.636 is not 18.64 until you round. 33.64%, 148 of 440, exceed 80 characters. 148 divided by 440 is 33.636%, which rounds to the 33.64% they print. 82 plus 148 is 230. 440 minus 230 is 210. The page does not print 210, which is the band the two sentences leave between 40 and 80. For Actions they print 28.90% below 40 characters and 15.65% above 80, and they do not print the counts. 0.2890 times 7,878 is 2276.742. 0.1565 times 7,878 is 1232.907. Neither is an integer, and neither is an installation id. Elsewhere they write 462 papers next to 1,434 authors and 5,937 developers and the same 8,318 products. 515 is not 462. 515 minus 462 is 53. The page does not print 53. Deployment is given as 1,800 Actions. 1,800 is not 7,878.

Do the three proofs on one real installation, in the organization that actually holds it. First, the binding. Copy the installation id, the app id, and the permission on the resource you were asked about. If suspended_at is set, write the time. If repository_selection is selected, name the repositories, and do not describe it as all. If single_file_name is config.yaml and a path is config.yml, write both. Do not pick the spelling you prefer. Second, the other installation. A different account login, or a different repository selection, is not this one. octocat with selected, and github with all, are that shape on the sample pages, and they are still samples, and they both print id 1. A catalog of 440 apps is not that second installation. If you cannot show an installation that is not this grant, you have a directory, not a record. Third, the other organization. A list that belongs to someone else's client does not contain this installation id. If the only list is a token on a laptop the agency takes home, write that. An organization you cannot open is the finding. It is not a reason to tell the client the app can read contents.

Three moves feel like the proof and are a second problem. Pasting the marketplace category because the permission was embarrassing, and then describing the missing id as a cleanup. Quoting 8,318 because it looks precise, while the install you were asked about is one row, and 8,318 is a catalog that also contains 7,878 Actions that are not Apps. Asking a model which permission was granted. The model will pick read or write. It will not open the installation. A branch name you have not kept, while the client is arguing about who can push, is which branch did that pull target?. Opening that screen does not name the app.

The path is ordinary when an operator can open one agency workspace without opening the next agency's workspace as the way to prove it. Gigbase is a multi-user agency management portal: projects, teams, clients, contracts, invoicing, and an admin-trained assistant, one workspace. The shape that matters here is one workspace you can point at, distinct from the next workspace. That case is not an installation ledger. Nothing in the description is a headcount, a duration, or a result figure. If the only control on the screen shows a project list and will not name an installation id, you do not have this proof. You have a portal.

There is a version of this afternoon where taking the work is the wrong purchase. The work is not sold under the agency's name. The client asked to meet the builders. The room only has a slide of the marketplace. The buyer only wants a template. Or the buyer wants a legal opinion on whether an install is a subcontract. A white label software development partner can work in the client's organization or in the agency's, under the agency's name. The partner does not become the installation. If the next slice is one capability and the acceptance sentence names the installation id, an AI integration sprint is the shape that can require the three proofs as the definition of done. Where you are not sure which organization the current app is installed on, a two-week AI readiness assessment maps the systems. The findings are yours. They are not a promise that 440 apps are this install, and they are not contents read.

The phase a schedule entered, and the voice a speech request used, are different objects: which phase did that schedule enter? and which voice did that speech use?. Do not record either on this page. A phase end is not an app id. A voice name is not a permission.

Before you tell the client the automation can see the repository, do the three proofs and write the id. Name the installation, the app, and the permission, or write that the installation is suspended or absent. Show a different installation that is not that grant. Show another organization's list that does not hold it. Do not paste a catalog count onto a null, and do not ask a model which of the sample ids it was. A paper can tell you what it counted on a marketplace, including the paper count that changes from 515 to 462. The binding is the installation you can defend.

Questions

Three records, in an organization the agency or the client can open. The installation id, the app id, and the permission, or a written line that the installation is suspended or absent. A different installation whose account or repository selection is not this one. Another client's organization that does not list this installation. If the single-file name and a path disagree, write both.

No. 8,318 tools on a marketplace, or 440 apps in that count, are not the installation id. A grant you can defend is the installation id, the app id, and the permission on this organization. 515 papers is not 462 papers, and config.yaml is not config.yml.

When the work is not sold under the agency's name, when the client asked to meet the builders, when the room only has a slide, when the buyer only wants a template, or when the buyer wants a legal opinion.

Find this useful? Tell Google to show you more of it.

Let's put AI to work in your business.

A 30-minute call. You bring the workflow or the roadmap — we'll tell you what's feasible, what it costs, and what we'd build first.

Book a call→