Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement Project-level environment variables #7295

Merged
merged 5 commits into from
Jan 17, 2022
Merged

Conversation

jankeromnes
Copy link
Contributor

@jankeromnes jankeromnes commented Dec 17, 2021

Description

Introduce Project-level environment variables:

  • [dashboard] Unify project-getting code into a ProjectContext helper
  • Implement a Variables page in Project Settings
  • Implement Project-level variables in server and gitpod-db
  • Expose Project-level variables in prebuilds
  • Expose Project-level variables in workspaces...
  • ...but also hiding certain variables in workspaces
  • ...and censoring them in logs too (image builds, prebuild logs, etc. in order to mitigate accidental leaks of secrets) (EDIT: follow-up)
  • Drive-by: Export server's censor function via gitpod-protocol (in order to use it in gitpod-db) (EDIT: Commit removed, censor code copy/pasted and specialized)
  • Drive-by: Always use the actual function name (arguments.callee.name) in checkUser and checkAndBlockUser (instead of re-typing/copy-pasting the function name and sometimes making mistakes) (EDIT: Commit removed again, arguments.callee is deprecated 🙄)

Related Issue(s)

Fixes #4456

How to test

  1. Log in to https://jx-project-variables.staging.gitpod-dev.com/projects
  2. In your User Settings, create an environment variable called USER with value user and pattern */*
  3. Next, create a project
  4. Navigate to Project Settings > Variables, and create a new variable (e.g. PROJECT with value project, visible in both Prebuilds and Workspaces)
  5. In the Project repository, create a new branch containing a .gitpod.yml file that looks like this:
tasks:
  - init: echo "USER: $USER, PROJECT: $PROJECT"
    command: echo "USER: $USER, PROJECT: $PROJECT"
  • Verify that, in the triggered prebuild (from the new branch created in 5.), only the PROJECT variable is defined (USER should still be undefined in the prebuild)
  • When you open a workspace for that new branch, both USER and PROJECT should be defined (not in the printed Prebuild logs, but in the interactive command & also in live Terminals)

Open question: If you open a workspace for the new branch as a new user who doesn't have access to the Project (i.e. the repository is public, and you open a workspace for it, which gives you a prebuild, but you have no access to the Gitpod Project) -- should you be able to see the Project variables? (Prebuild/non-prebuild consistency says "yes", secrets say "no", maybe this should be configurable for each variable, see #4456 (comment)) (EDIT: Visibility is now configurable)

Release Notes

Introduce Project-level environment variables

Documentation

  • /werft with-clean-slate-deployment

/uncc

@jankeromnes
Copy link
Contributor Author

jankeromnes commented Dec 17, 2021

/werft run with-clean-slate-deployment

👍 started the job as gitpod-build-jx-project-variables.3

@roboquat roboquat added size/XL and removed size/XXL labels Dec 17, 2021
@jankeromnes jankeromnes force-pushed the jx/project-variables branch 3 times, most recently from 4d73d88 to a056a54 Compare December 24, 2021 17:34
@jankeromnes jankeromnes force-pushed the jx/project-variables branch 2 times, most recently from 600a708 to 8585c0d Compare December 30, 2021 13:40
@jankeromnes
Copy link
Contributor Author

jankeromnes commented Dec 30, 2021

/werft run

👍 started the job as gitpod-build-jx-project-variables.10

@jankeromnes jankeromnes force-pushed the jx/project-variables branch 6 times, most recently from 2ceb652 to 641a6bc Compare January 4, 2022 16:50
@roboquat roboquat added size/XXL and removed size/XL labels Jan 4, 2022
@codecov
Copy link

codecov bot commented Jan 4, 2022

Codecov Report

Merging #7295 (1f6b435) into main (2773b35) will increase coverage by 1.68%.
The diff coverage is n/a.

Impacted file tree graph

@@            Coverage Diff            @@
##            main    #7295      +/-   ##
=========================================
+ Coverage   8.69%   10.38%   +1.68%     
=========================================
  Files         33       18      -15     
  Lines       2323      992    -1331     
=========================================
- Hits         202      103      -99     
+ Misses      2117      888    -1229     
+ Partials       4        1       -3     
Flag Coverage Δ
components-gitpod-cli-app 10.38% <ø> (ø)
components-local-app-app-darwin-amd64 ?
components-local-app-app-darwin-arm64 ?
components-local-app-app-linux-amd64 ?
components-local-app-app-linux-arm64 ?
components-local-app-app-windows-386 ?
components-local-app-app-windows-amd64 ?
components-local-app-app-windows-arm64 ?
installer-raw-app ?

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
installer/pkg/common/render.go
components/local-app/pkg/auth/pkce.go
installer/pkg/components/ws-manager/rolebinding.go
installer/pkg/common/storage.go
installer/pkg/common/display.go
installer/pkg/common/objects.go
installer/pkg/components/ws-manager/configmap.go
components/local-app/pkg/auth/auth.go
installer/pkg/components/ws-manager/tlssecret.go
installer/pkg/common/common.go
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2773b35...1f6b435. Read the comment docs.

@jankeromnes jankeromnes force-pushed the jx/project-variables branch 2 times, most recently from b5e00eb to 3801563 Compare January 5, 2022 14:30
@@ -41,7 +41,8 @@ export default function Modal(props: {
return () => {
window.removeEventListener('keydown', handler);
};
}, []); // Empty array ensures that effect is only run on mount and unmount
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [props.onClose, props.onEnter]);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note: This was required because apparently state variables (like name: string and value: string in AddVariableModal) get "captured" in the onClose / onEnter lambdas, thus causing these functions to always use initial state values (i.e. empty string) instead of updated state values (i.e. whatever name/value a user typed).

The solution was to make this effect depend on onClose and onEnter, such that, if these functions change (they do change every time a captured state variable changes), the handler gets re-registered properly.

@jankeromnes
Copy link
Contributor Author

jankeromnes commented Jan 5, 2022

Okay, calling this ready for review 🎉

Screenshot 2022-01-05 at 16 54 42 Screenshot 2022-01-05 at 16 54 55

@geropl and/or @AlexTugarev, could you please take a look at the code changes?

@gtsiolis could you please take a look at the new Project Variables page UX?

(Happy to discuss / answer any question sync or async 🙏)

@jankeromnes jankeromnes marked this pull request as ready for review January 5, 2022 15:57
@gtsiolis
Copy link
Contributor

gtsiolis commented Jan 14, 2022

Taking another look at the UX changes here! 👀

@geropl
Copy link
Member

geropl commented Jan 14, 2022

@jankeromnes Thx for putting in all this effort. Love the explicitness of the new messages! ❤️

/lgtm
/hold

So @gtsiolis can review as well

@roboquat
Copy link
Contributor

LGTM label has been added.

Git tree hash: 34d504ab9541adf0333b4aec043af2382ba2786d

@roboquat
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: geropl, gtsiolis

Associated issue: #4456

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

Copy link
Contributor

@gtsiolis gtsiolis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This took slightly longer than expected. 💭

@jankeromnes I've left some final comments below regarding UX changes. Feel free to create follow up issues for each one of them if needed. 🏀

}

return <Modal visible={true} onClose={props.onClose} onEnter={() => { addVariable(); return false; }}>
<h3 className="mb-4">Add Variable</h3>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggestion: Even if we don't have the update operations here, renaming this as described in /7295/files#r781502096 to match the voice and tone used in user-specific environment variables would be nice!

Suggested change
<h3 className="mb-4">Add Variable</h3>
<h3 className="mb-4">New Variable</h3>

components/dashboard/src/projects/ProjectVariables.tsx Outdated Show resolved Hide resolved
components/dashboard/src/projects/ProjectVariables.tsx Outdated Show resolved Hide resolved
return <Modal visible={true} onClose={props.onClose} onEnter={() => { addVariable(); return false; }}>
<h3 className="mb-4">Add Variable</h3>
<div className="border-t border-b border-gray-200 dark:border-gray-800 -mx-6 px-6 py-4 flex flex-col">
<AlertBox><strong>Project variables might be accessible by anyone with read access to your repository.</strong><br/>Secret values can be exposed if they are printed in the logs, persisted to the file system, or made visible in workspaces.</AlertBox>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue(non-blocking): I've been trying to propose some new colors for the alert component as seen in the designs in #7295 (comment) but let's not increase the scope of this PR with this. Added #7613 regarding alert component colors, etc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Many thanks for filing this follow-up!

More than happy to implement the adjustments -- really like the new design. Please simply post a spec to the issue + remove needs design label + schedule, as usual 😊 (you could even directly assign me to it 🚀 I'm looking forward to have this fixed)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Je vous remercie, @jankeromnes!

<ItemField className="flex justify-end">
<ItemFieldContextMenu menuEntries={[
{
title: 'Delete',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: Still not entirely sure if not being able to edit or update the variable is better but I understand the security concerns. From what I've seen there are two approaches:

🅰️ Systems do not allow editting such values but only allowing to delete them.
🅱️ Systems allow users with specific permissions to read, update and delete such values.

Since we do have two different user roles (OWNER, MEMBER), we could hide the variable menu or disable actions on variable for MEMBERS.

suggestion: I'd be in favor of providing more user control and allowing read and update permissions, however, I agree @jankeromnes, let's go with a boring (simple) solution to disable editing the variables for now and come back to this if users find this idea useful.

<ItemField className="flex justify-end">
<ItemFieldContextMenu menuEntries={[
{
title: 'Delete',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue: We should probably ask for user confirmation before deleting, as we do with user-specific environment variables.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for noticing! I personally think we don't need to be overly cautious here (i.e. clicking once on a red Delete button is likely already sufficient intent, and this action doesn't have surprising chain reactions as consequence).

Leaving this as an optional follow-up if we really feel we need the extra user confirmation.

components/dashboard/src/projects/ProjectVariables.tsx Outdated Show resolved Hide resolved
components/dashboard/src/projects/ProjectVariables.tsx Outdated Show resolved Hide resolved
return <Modal visible={true} onClose={props.onClose} onEnter={() => { addVariable(); return false; }}>
<h3 className="mb-4">Add Variable</h3>
<div className="border-t border-b border-gray-200 dark:border-gray-800 -mx-6 px-6 py-4 flex flex-col">
<AlertBox><strong>Project variables might be accessible by anyone with read access to your repository.</strong><br/>Secret values can be exposed if they are printed in the logs, persisted to the file system, or made visible in workspaces.</AlertBox>
Copy link
Contributor

@gtsiolis gtsiolis Jan 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: It took me a while to wrap my head around the security cases here. 😇

Some improvements could include:

  1. Making the alert title brief and short in one line.
  2. Avoiding complex state handling for users by default.

suggestion: For the second point I still think that having a sensible default where variables can be exposed everywhere by default instead of requiring users to think everytime could be better. Here's how the copy could look like although I could be wrong on terminal access only:

BEFORE AFTER
Screenshot 2022-01-14 at 8 01 26 PM (2) Screenshot 2022-01-14 at 8 01 10 PM (2)

Let me know what you think!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The message at the top could be a little clearer about how prebuild variables could leak into workspaces.
  • The current default to Hide in workspaces is good IMO because it errs on the side of less exposure.
  • I think we can leave out the extra instruction for what it means to uncheck the checkbox.

Suggest the following:

Warning
Even with Hide in Workspaces checked, a project-specific environment variable may become exposed to anyone who can start a workspace e.g. if logged or persisted to the file system.

Name
[ _ _ _ ]

Value
[ _ _ _ ]

☑️ Hide in Workspaces
Project-specific environment variables are always visible in prebuilds.

(after unchecking)

NOTE
This environment variable will be visible to anyone who starts a Gitpod workspace on this repository.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the excellent feedback here! 🙏

Phew. After splitting a few more hairs on this, I think I've reached an optimum consensus solution on the wording:

Screenshot 2022-01-17 at 19 09 11 Screenshot 2022-01-17 at 19 09 19

Going to ship this 🚢 (but happy to further split hairs in follow-up PRs 😅)

Copy link
Contributor

@gtsiolis gtsiolis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Three last comments. Promise! 🙂

@jldec
Copy link
Contributor

jldec commented Jan 14, 2022

Awesome work @jankeromnes - thanks for going the extra mile with hiding in workspaces 🙏

@roboquat
Copy link
Contributor

New changes are detected. LGTM label has been removed.

@jankeromnes
Copy link
Contributor Author

jankeromnes commented Jan 17, 2022

Just waiting for a last build to triple-check everything, then shipping this. 🚢

(Manually carrying over pre-nit / pre-rebase LGTM, keeping hold for now.)

@jankeromnes
Copy link
Contributor Author

jankeromnes commented Jan 17, 2022

Everything seems to still work as expected! (Tested the variable management UI, but couldn't test prebuilds/workspaces because they're currently broken in core-dev (internal)).

Thus, releasing the breaks! 🚀 ✨

/unhold

@roboquat roboquat merged commit bb80946 into main Jan 17, 2022
@roboquat roboquat deleted the jx/project-variables branch January 17, 2022 18:37
@shaal
Copy link
Contributor

shaal commented Jan 17, 2022

Thank you for working on this!
When will we be able to test Project-level environment variables in gitpod.io ?

@jankeromnes
Copy link
Contributor Author

jankeromnes commented Jan 18, 2022

@shaal Sure, my pleasure! This should go live in about an hour with the regular twice-a-week deployment. 📅📅

EDIT: Deployment got delayed a bit due to technical issues. Should still go live today tomorrow morning though.

@roboquat roboquat added deployed: webapp Meta team change is running in production deployed Change is completely running in production labels Jan 19, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved deployed: webapp Meta team change is running in production deployed Change is completely running in production release-note size/XXL team: webapp Issue belongs to the WebApp team
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Introduce project-level environment variables
8 participants