'Including' private project file using `$CI_JOB_TOKEN` - gitlab

What I got so far is, it is possible to Authenticate with Personal Access Token and include external CI script but a cleaner approach would be to get access using $CI_JOB_TOKEN since it is more secure and restricted. I am looking into if it can be done this way -
include 'https://gitlab-ci-token:${CI_JOB_TOKEN}#raw-file-url'
I have tried to curl in this format in a dummy script job, but it fails to fetch the file.
Apparently, an external script can be imported using file API and $CI_JOB_TOKEN (https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2346/diffs), but I am looking into if include feature also support this. Any suggestion on how to achieve that is appreciated.

Unfortunately, CI_JOB_TOKEN is very limited in scope. As of today (GitLab 11.0), you can only do two things with it:
Authenticate with the GitLab Container (Docker) Registry
Authenticate to trigger a multi-project pipeline (EE only)
References:
https://docs.gitlab.com/ce/ci/variables/
https://docs.gitlab.com/ee/ci/variables/
So you cannot use CI_JOB_TOKEN to download a file from another repository, neither via the raw endpoint (/raw/<ref>/<path>) nor the API.
Unfortunately, deploy keys don't help either -- they are only for SSH.
The only workable solution I've come up with is to use a separate user:
Create a new user with Reporter role.
Create a personal access token (/profile/personal_access_tokens) for that user with api and read_repository rights.
Add this token as a secret variable in the project CI/CD settings. Call it e.g. BUILD_USER_TOKEN.
Use $BUILD_USER_TOKEN in your CI script to access the API or project files.
This is a huge hack, and I really hope to see GitLab make CI_JOB_TOKEN a first-class, read-only (?) token with rights to specified resources.

Still there is no support for the CI_JOB_TOKEN to have a useful API access. But they are working on it https://gitlab.com/groups/gitlab-org/-/epics/3559

Related

How to create a Git tag in Gitlab CI without using personal credentials?

I'm using GitLab Enterprise Edition 14.6.5-ee
I want to create a Git tag automatically when I merge a branch back to master. I'm fine with the actual Git commands; the problem is with the authentication: the build bot doesn't know how to authenticate back to the server. There's an answer here how to set up SSH keys. But this requires me to use my personal credentials, which is just wrong, because it's not me creating the tag; it's the build bot.
Seriously, it just doesn't make sense to say that the bot doesn't know how to authenticate. I mean, it just pulled the freakin' code from the repo! So why is it such a big leap from being able to pull code to being able to push code?
Any ideas how to automate the creation of tags without using my personal credentials?
CI jobs do have a builtin credential token for accessing the repository: the $CI_JOB_TOKEN variable. However this token only has read permissions, so it won't be able to create tags. To write to the repository or API, you'll have to supply a token or SSH key to the job. However, this doesn't necessarily have to be your personal token.
There are a few ways you can authenticate to write to the project without using a personal credential:
You can use project access tokens
You can use group access tokens -- these are only exposed in the UI after GitLab 14.7
You can use deploy SSH keys (when you grant read-write to the key)
So why is it such a big leap from being able to pull code to being able to push code?
This is probably a good thing. While it may require you to do extra work in this case, the builtin job authorization tries to apply the principle of least privilege. Many customers have even argued that the existing CI_JOB_TOKEN permissions are too permissive because they allow access to read other projects!
In any case, it is on GitLab's roadmap to make these permissions more controllable and flexible :-)
Alternatively, use releases
If you don't mind creating a release in addition to a tag, you could also use the release: keyword in the CI yaml as an easy way to create the tag.
It's somewhat of an irony that the releases API allows you to use the builtin CI_JOB_TOKEN to create releases (and presumably tags) but you cannot (as far as I know) use CI_JOB_TOKEN on the tags API to create a tag.
However, in this case, it will still have the effect that the releases/tag appear to be created by you.

Is it safe to put in secrets inside Google App Script code?

I'm creating a Google Workspace Add-On and need to make some requests using OAuth. They provide a guide here explaining how to do so. In the sample code, it's suggested that the OAuth client secret be inline:
function getOAuthService() {
return OAuth2.createService('SERVICE_NAME')
.setAuthorizationBaseUrl('SERVICE_AUTH_URL')
.setTokenUrl('SERVICE_AUTH_TOKEN_URL')
.setClientId('CLIENT_ID')
.setClientSecret('CLIENT_SECRET')
.setScope('SERVICE_SCOPE_REQUESTS')
.setCallbackFunction('authCallback')
.setCache(CacheService.getUserCache())
.setPropertyStore(PropertiesService.getUserProperties());
}
Is this safe for me to do?
I don't know how Google App Script is architected so I don't have details on where and how the code is being run.
Most likely it is safe since the script is only accessible to the script owner and Workspace Admins if it is for Google workspace (which may or may not be an issue).
Well, you can add some security/safety by making use of a container, by using Container-bound script which makes use of Google Spreadsheet, Google Doc or any other that allows user interaction. Or a standalone script but also makes use of other way to connect to UI for interaction. Refer to this link for more detailed explanation on that: What is the appropriate way to manage API secrets within a Google Apps script?
Otherwise, the only way I see that you can do is store the keys and secrets in User Properties. Here's how you can do it: Storing API Keys and secrets in Google AppScript user property
Also you can refer to this link below for more general information on how you can manage or add some security: https://softwareengineering.stackexchange.com/questions/205606/strategy-for-keeping-secret-info-such-as-api-keys-out-of-source-control

Gitlab CI Pipeline with Token

I created Personal Access Token in gitlab.com to read the gitlab api because I want to create some documentation about my repos in asciidoc automatically. Basically this works in a local script.
Now I want to turn this into a Giutlab CI pipeline. As of now the token is part of my local script. But I don't want this token to be readable in a public repo. Is there a way to get the token from the pipeline in a secure way without putting it into the .gitlab-ci.yml in plain text or any other reusable form?
Yes, in your gitlab project Settings > CI / CD > Variables
There you can add Key value pairs which can be "masked" so aren't visible in scripts.
But you should be aware this isn't fully "secure" take a look at this

Call GitLab API without personal "Private Token"

Is there a way to call GitLab API apart from using personal "PRIVATE TOKEN"?
Problem with PRIVATE TOKEN is , it need to be updated in settings -> CI/CD -> Environment Variables which is accessible to anyone with maintainer privilege.
And its need to be updated, if the developer moves out of the project .
I found out there is no other way to do it and alternate implementation still in GitLab's backlog.
But just to ensure & looking for if there is any other work around exist.
As of Gitlab 13.9, there's no way to use the API without someone's access token, but you could create a "dummy" Gitlab user and use an access token of theirs if you didn't want to use one belonging to a person.

GitHub access token with read-only access to private repositories

I have a project with a Node dependency on a private Git repository. I need to be able to run npm install without being prompted to enter a password or allow an SSH connection, so I'm using an access token that I created on GitHub in my package.json:
"dependencies": {
"sass-theme": "git+https://[token]:x-oauth-basic#github.com/MyOrg/sass-theme.git#v1.0.2",
"node-sass": "^4.5.0"
}
This project is shared with dozens of other people, so obviously I don't want to keep my token in source control. I know I can create a read-only deployment key on GitHub, but I believe that would require other developers to import the SSH key to build the project locally.
Is it possible to create an access token that can be shared but that has read-only access to clone the repository?
The most straightforward way I can think of to create a token that provides read-only access to a private repo is to:
Have a user who has read-only access to the given private repo
(and ideally, not much else)
As that user create a Personal Access Token with the "repo" scope
It would be best if they didn't have access to other orgs/repos, since the "repo" scope grants the user total control over any repos that user has write access to.
I know in an Enterprise solution we would do that with a System ID, but on GitHub you can instead create a Machine User.
Deploy keys are the way to go. By default they don't allow write access and they are scoped to the specific repository (unlike the GitHub personal access token). So you can now generate a private/public key pair, set one as read/pull only deploy key on a single repository in GitHub and use the private key in your CI.
For instance run a bash script:
eval "$(ssh-agent -s)";
ssh-add <your private deploy key>;
Now your CI has rights to access private repo's during the build.
You can add a Deploy key by going to your repository on Github and then clicking Settings > Deploy keys > Add deploy key
If you think it's a bad idea to put your credentials in your source code (as you should!) then you have few options:
Keep it hosted in a private GitHub repo but add those dozens of other people as collaborators to this repo (with read only access).
Keep it hosted in a private GitHub repo but owned as an organization and add those people to the organization.
Publish it as a private npm module.
Publish it in a private npm registry.
Include the dependency in the source code of the program that needs it.
The last one is basically like including the node_modules in the original code that uses that module so of course it's not pretty. Hosting your own npm registry is not trivial but you can automate adding users that way. Publishing private npm module is not free. Maintaining an organization full of people who should be able to access your repo is annoying.
Keep in mind one thing: if you share your credentials with more than one person, expect everyone to eventually have access to it, it's just a matter of time. The credentials could have a limited scope, it can be a read only deploy key or a machine user with restricted access, but if it is distributed it will leak eventually as it always does, especially when you share it with dozens of people. It's much better to keep a list of people who can access the code, and you can automate keeping that list up to date using the GitHub API.
I would never recommend distributing credentials in the source code of the project, no matter how limited access those credentials provide.
It's ugly that there are no scope for Read-only access to private repo.
What I suggest is to create a new token even with read/write as a Temporary token. Then pull/fetch the changes and delete the Token directly.
Apparently, GitHub has heard you and added a new beta feature called "Fine-Grained Tokens"!
https://github.blog/2022-10-18-introducing-fine-grained-personal-access-tokens-for-github/
"Create a fine-grained, repository-scoped token suitable for personal API use and for using Git over HTTPS"
Go to setting/developer settings/Personal Access Tokens/Fine grained token

Resources