GitHub App - generate permanent installation access token - authentication

Is there way to let the user who installs a GitHub App generate a permanent installation access token which can be used by the app to authenticate and perform actions as that app?
I am wanting to create a simple GitHub App that will run on a CI server and comment on PRs with data from one of the tests.
As this app is being run by the user on their CI server there is no place to store the private key for the GitHub App that would usually be used to generate the access token as described here.
Ideally if the user could generate a permanent installation access token for the app they could securely provide that key to the app when it runs on the CI server so the app can communicate with the GitHub API and authenticate as the app.
I realize that the user could provide a user access token and the app could authenticate that way - but when the app comments it needs to show up as originating from the app, not the user (and I don't believe that would happen if the app authenticates with a user access token).

I think you might be confusing "GitHub Apps" with the more generic idea of tools that access the GitHub API. The Apps system a specific way to build hosted services for GitHub that has its own authentication model. Users can't run an App themselves as it is only designed around hosted/SaaS tooling. For things that someone would run themselves, you would need the end user to create a new user account on GitHub for the bot and then authenticate as it (either OAuth or personal access token, doesn't matter).

This is an old question, but in the interest of having the correct info here...
#osowskit's answer is correct in terms of mentioning you need to use JWT but not in terms of that has to be done using webhooks. There are indeed advantages of using Apps for access control - the GitHub App can be given specific access for only some repos. Now at least some CI systems (well at least Jenkins) support GitHub App access natively for some uses.
The basic flaw in the original request was the request of a permanent PAT associated with the App. This is not how they work. Instead you generate a Private Key for the App and it is this that should be stored in the CI secrets system. Now you do indeed need some sort of PAT to actually do the action - here to add the PR comment - it is just that you don't have a permanent one. Instead you generate temporary PATs each time you need to run - IIRC these PATs last for about an hour, so are useful for most single jobs but are to be generated each time and not stored as such.
Once you get the code, it is no big deal using the jwt tokens - it just involves a couple of extra REST calls.

Is there way to let the user who installs a GitHub App generate a permanent installation access token which can be used by the app to authenticate and perform actions as that app?
Maybe but it shouldn't be necessary. A GitHub App will only perform actions on data a user grants it access to. Any data modified on GitHub by the App will appear as an action 'performed' by the App.
Ideally if the user could generate a permanent installation access token for the app they could securely provide that key to the app when it runs on the CI server so the app can communicate with the GitHub API and authenticate as the app.
This shouldn't be necessary based on the information you've provided. Users grant access to a GitHub App to access specific resources and listen for specific events; a GitHub App needs a installation ID (or multiple installation IDs) to interact with GitHub data.
The good news is that for the CI workflow you outlined, GitHub would send the installation ID in the webhook payload - likely a push event.
I realize that the user could provide a user access token and the app could authenticate that way - but when the app comments it needs to show up as originating from the app, not the user (and I don't believe that would happen if the app authenticates with a user access token).
Generating a personal access token (PAT) isn't required and GitHub Apps were created to avoid creating service accounts or adding credentials to your CI environment.
Author your GitHub App to listen for webhook events.
On receiving an event, parse the payload for the installation id
Generate an installation access token by authenticating as an application after creating a JWT.
Use the installation access token generated above to modify data. Note that this token expires in an hour.
Profit!

Related

How to get authorization code in BigCommerce to generate access token once the app is already installed in a store

I am providing an integration to BigCommerce from our website.
I see that the auth url is called with the authorization code when app is first installed. I need to know how I can generate the authorization code with an app already installed.
I need it because there's a case where the user removes the integration from our website but our app is still installed in his store in BigCommerce. I want to show something like a 'connect' button which the user can click to generate a new access token and connect his store to our website.
I understand that I can reuse the same access token that he had before he removed the integration, but then what if the user connects a second account in our website to his BigCommerce store. In this case the access token will need to be passed between two different accounts in our website and will be an issue.
An app should only connect to a store actively, in a process that will install the app. If you're offering the ability to disable the integration outside of BigCommerce, the app should be uninstalled at the same time from the store. The same OAuth token is required to authorize any API requests for the app, which is why it needs to be stored after installation.

Does Keycloak support some form of middleman authentication?

I'm using keycloak to let my users authenticate with my application. And i am trying to migrate some functionality to a few plugins, e.g. a wordpress plugin. For these plugins i want to use a generic solution so I found the following authentication process from Microsoft (https://learn.microsoft.com/en-us/office/dev/add-ins/develop/auth-external-add-ins#middleman-services) and Adobe ( https://adobexdplatform.com/plugin-docs/tutorials/how-to-integrate-with-OAuth/).
I managed to hack my way around the process to get this working with keycloak. But at this moment I'm a bit concerned about the security risk that go with this process.
The process in steps
the (plugin) client asks to backend server to generate a code to identify the user.
the (plugin) client start polling the backend for an authentication code (no response yet, since the user is not logged in yet).
the plugin opens a browser window or tab with the keycloak loginpage. Everything is the same as the normal process, but this time we add an redirect uri with the code generated in step one, which identifies the user.
once the user is logged in the user gets redirected in the browser to an endpoint where the code from step one is linked to the access token retrieved in this step.
the polling from step 2 now returns the access token to the (plugin) client.
The reason I need to poll for the access token is because I want to make a generic login process for all client.
In short, I want to know what the security risks are, given the steps above. Also I can not seem to find any information of keycloak that they want to implement such feature. Does anyone know if they want to implement this, since many other plugins do offer tis feature to authenticate outside the plugin with a popup window and retrieving the accesstoken by "polling" the server.
Thanks for the help.

What is the correct way to use OAuth for mobile and website consuming my own API?

I have a question more related to the way OAuth 2 is working but since using IdentityServer to implement OAuth I think it's relevant. I could not find an answer anywhere.
I'm building a website and a mobile app that consumes my own API. Each user of my app will have a username and password, that will give him access to the app/website and though the API to his information.
I'm not sure about the right way to handle the flow for user login:
On the website I have my own designed login form. I don't want to move the user to my auth server to login, and then have him approve the information he gives - he is the user on my system - I have access to all information - kida like facebook has a login and access to the informatio - they don't ask what you're willing to give them. So is implicit really the way for this?
On the mobile app I also have a login form and now I read here (https://datatracker.ietf.org/doc/html/draft-ietf-oauth-native-apps-10) that the OAuth approach is to have the login in a WebView?? Doesn't look like facebook login is in a WebView on their mobile app.
The approach I was first lookin at is the Resource Owner. Users will login, get the token and the refresh token and can start working against my APIs. But storing my client_id and secret on the mobile app? on the website javascript files? doesn't feel right. I can of course make a call to an API that will mask those and be a proxy to the login process... but... (read #4).
In the future I would like to allow access for third-party developers. For them to allow login for users of my system I will use the implicit flow. Also, I plan for those developer accounts to have restricted API access (for example, the number of calls to the API will be limited by plan). What prevents those developers from asking for the username and password of their account on my system on their website, getting the response from my servers with the access token and refresh token, and using my API however they want, without restrictions, and having access to the entire user profile?
Lets say I'm sticking to the resource owner flow, receiving back from the server a token and a refresh token. What should I store on the mobile device and how? What should be stored in the browser and how? the refresh token? and each time he opens the app get a new updated token with that refresh token?
Edit
Just to clarify, because I find a lot of lectures and articles that explain the process from an API consumer point of view (ie. the third-party developer): I am the API owner and the auth server owner, I'm the owner of the user accounts (they are my users of my services), I'm also my own consumer (though the website and the mobile app), and in the future I want to enable third-party developers to allow my users to login with their accounts of my service (kinda like Facebook or Google)
You're correct that you shouldn't store the client_secret in your app, but I doubt you will get around storing the client_id. You could disable the consent screen for your app as well, and build a native login view. You need to store the access_token and the refresh_token on the device (maybe encrypted in a database) if you don't want the user to login everytime they use your app.
As for problem 4, you could do the following:
Embed the client_secret in your (web) app
Set up which hosts have access to your api on the IdentityServer
The IdentityServer generates a salt and sends it to the client
The client calculates a session_secret using hash(ip_address + session_salt)
The client uses the session_secret and the client_secret for the API call
Server validates the hash and client_secret
It's nearly impossible to completely prevent someone from using your API. But you should add various rate limiting methods, such as limiting IP addresses, API calls etc. But nothing will stop someone decompiling your app and accessing your client_id.

Webhook + Server-side Authentication

I have a user provide me the organization he wants to Sync with our system. We create the hooks afterwards for each App of the Organization.
The only workaround I found is to ask for each App ID and Token or the username authentication.
How can a Webhook be authentified to have the right to get items from all Apps at the same time? (like a server-side authentication)
There are a couple of options: The best is to contact Podio support and get an increased trust level for your API key. Then app tokens can be retrieved through the API and you can fully automate hook creation.
The alternative is to create a user that's a member of all spaces which you can authenticate as using password-based authentication.

Authenticating against a realtime-server used in a Symfony2 project

I recently started a new project using different carefully-chosen technologies, my project is built as follow :
The approach is API-Centric, which means I'm building a website and an iOS app communicating with an API written using Symfony2. I've successfully managed to write my API, and it is perfectly working.
To gain access to the services provided by the API, the main actors (the website users, the iOS app users and the developers) can authenticate theirself in several ways :
Clients can gain access with a login/password couple through the website interface which is communicating directly with the API through AJAX to validate the provided credentials and set a session. So, when someones logs in our website, they have automatically access to the API as well.
Developers can authenticate theirself through the API using HTTP-Basic over SSL, which will as well generate a session and give them access to the services they are authorized to call.
Also, Developers and clients can gain access to the website and the API using their facebook account through the Facebook Connect functionality. This deletes the step where each actor has to create an account on our website.
So basically, the credentials are provided either through HTTP-Basic or using the Facebook Login functionality.
Now that my authentication system is working and that my clients are able to access the website, I would like them to connect to a real-time server when they log in. Like in Facebook or Google+ if you want where the real-time server manages chat and push informations.
In this case i'm using Node.js and the powerfull socket.io library to manage everything that deals with the real-time side.
Of course, the real-time service will need some credentials to authenticate the user since he is authenticated to the Symfony security system with a session but is not authenticated against the real-time server.
A solution I've been thinking about would be to use the PdoSessionStorage in my API (Symfony side) and store all the active sessions in a database such as MySQL or PostgreSQL. Doing so, I would be able to send to my real-time server the session id generated by symfony and check on the database if the session id provided is correct or not. If he is I'll let the user access the services provided by my real-time server and associate his session with an identity.
But I really don;t know if this is a good solution and I would like some more experienced advices on this and on how to deal with this issue.
Note : For some reasons, I cannot implement OAuth even if it could be a solution to solve this issue using a Single Sign On approach.