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

feat: commit signing using ssh and gpg #1146

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

bryans-go
Copy link
Contributor

@bryans-go bryans-go commented Sep 24, 2024

feat: commit signing using ssh and gpg

Description

add support for commit signing when adding git provider(s)

  • This change requires a documentation update
  • I have made corresponding changes to the documentation

Related Issue(s)

Closes #370
/claim #370

Screenshots

image

Notes

In order to sign your commits with ssh . ssh keys need to be present on your local system and should be added to your github or gitlab account. my pr simplifies the work for manually doing setup for ssh commit signing in the gitconfig file of the project.
for the ssh key field : paste the same key that you pasted in the add ssh key in github or gitlab

@bryans-go bryans-go requested review from a team as code owners September 24, 2024 16:22
@algora-pbc algora-pbc bot mentioned this pull request Sep 24, 2024
@bryans-go
Copy link
Contributor Author

@Tpuljak
image
can you please assist here. I am succesfull in adding git provider but these values are not getting stored and am not able to understand what to do

@bryans-go bryans-go marked this pull request as draft September 24, 2024 16:34
@Tpuljak
Copy link
Member

Tpuljak commented Sep 25, 2024

@Tpuljak image can you please assist here. I am succesfull in adding git provider but these values are not getting stored and am not able to understand what to do

@bryans-go from what I can see, you don't pass the properties from SetGitProviderConfig to GitProviderConfig here https://github.com/daytonaio/daytona/blob/main/pkg/api/controllers/gitprovider/gitprovider.go#L134

@bryans-go bryans-go force-pushed the commits-git branch 3 times, most recently from 0660fde to 25fea9e Compare September 27, 2024 03:54
@bryans-go bryans-go marked this pull request as ready for review September 27, 2024 04:09
@bryans-go
Copy link
Contributor Author

bryans-go commented Sep 27, 2024

asciinema

@bryans-go
Copy link
Contributor Author

bryans-go commented Sep 27, 2024

image

image
now the ssh signing is working perfectly @Tpuljak
Some of the git providers does not show verified commits bagde even on signed commits by git while some also dont have proper docs on this . what should we do there ?

pkg/db/dto/git_provider.go Outdated Show resolved Hide resolved
pkg/db/dto/git_provider.go Outdated Show resolved Hide resolved
pkg/git/service.go Outdated Show resolved Hide resolved
pkg/gitprovider/types.go Outdated Show resolved Hide resolved
pkg/gitprovider/types.go Outdated Show resolved Hide resolved
pkg/server/gitproviders/service.go Outdated Show resolved Hide resolved
pkg/server/gitproviders/service.go Outdated Show resolved Hide resolved
@Tpuljak
Copy link
Member

Tpuljak commented Sep 27, 2024

Some of the git providers does not show verified commits bagde even on signed commits by git while some also dont have proper docs on this . what should we do there ?

Could you let us know which providers don't show the verified badge but should?

P.S. Nice work on the solution!

@bryans-go
Copy link
Contributor Author

https://jira.atlassian.com/browse/BCLOUD-3166. Bitbucket doesn't have this feature yet and gitness don't have a proper docs on ssh and gpg signing while

@Tpuljak
Copy link
Member

Tpuljak commented Sep 27, 2024

https://jira.atlassian.com/browse/BCLOUD-3166. Bitbucket doesn't have this feature yet and gitness don't have a proper docs on ssh and gpg signing while

Then let's not show that input at all if the user selects Bitbucket or Gitness

@bryans-go
Copy link
Contributor Author

Ok

@bryans-go
Copy link
Contributor Author

@Tpuljak Done

@Tpuljak Tpuljak mentioned this pull request Sep 30, 2024
6 tasks
pkg/gitprovider/types.go Outdated Show resolved Hide resolved
pkg/views/gitprovider/select.go Outdated Show resolved Hide resolved
@bryans-go
Copy link
Contributor Author

@bryans-go I had something else in mind with https://github.com/daytonaio/daytona/pull/1146/files#r1778545525.

"none" shouldn't be defined as an option here.

The solution I was aiming for included setting up a variable inside GitProviderSelectionView that would be a helper variable for selecting the signing method. It would include ssh gpg and none as options. After the form runs inside that function, you would check the value of that variable and assign GitProviderView to the appropriate value (if none then nil).

demo
@Tpuljak I did what you said but problem is that due to the fact that signing method is a enum . the following problem has arisen. please assist with it

@Tpuljak
Copy link
Member

Tpuljak commented Sep 30, 2024

@bryans-go I had something else in mind with https://github.com/daytonaio/daytona/pull/1146/files#r1778545525.
"none" shouldn't be defined as an option here.
The solution I was aiming for included setting up a variable inside GitProviderSelectionView that would be a helper variable for selecting the signing method. It would include ssh gpg and none as options. After the form runs inside that function, you would check the value of that variable and assign GitProviderView to the appropriate value (if none then nil).

demo demo @Tpuljak I did what you said but problem is that due to the fact that signing method is a enum . the following problem has arisen. please assist with it

@bryans-go please try to do some debugging yourself. Not completely sure but this might be part of the issue. The signing method is a string when passed here when it should be a pointer to a string.
Also, make sure to wipe your config between these changes since these are all breaking to one another.

@bryans-go
Copy link
Contributor Author

bryans-go commented Sep 30, 2024

gitProviderAddView.SigningMethod = nil
I added the following line by explicitly setting the value as nil, and now everything works perfectly.

PS: I tried setting signing method as pointer to string but it didn't worked as expected but the following method was successful .

pkg/views/gitprovider/select.go Outdated Show resolved Hide resolved
pkg/views/gitprovider/select.go Outdated Show resolved Hide resolved
pkg/cmd/gitprovider/add.go Outdated Show resolved Hide resolved
pkg/cmd/gitprovider/delete.go Outdated Show resolved Hide resolved
pkg/views/gitprovider/select.go Outdated Show resolved Hide resolved
pkg/views/gitprovider/select.go Outdated Show resolved Hide resolved
pkg/api/controllers/gitprovider/dto/dto.go Outdated Show resolved Hide resolved
pkg/api/controllers/gitprovider/dto/dto.go Outdated Show resolved Hide resolved
pkg/db/dto/git_provider.go Outdated Show resolved Hide resolved
pkg/cmd/gitprovider/add.go Outdated Show resolved Hide resolved
@bryans-go bryans-go requested a review from Tpuljak October 1, 2024 10:34
@bryans-go bryans-go changed the title feat: commit signing using ssh or gpg feat: commit signing using ssh and gpg Oct 1, 2024
pkg/api/controllers/gitprovider/dto/dto.go Outdated Show resolved Hide resolved
pkg/views/gitprovider/select.go Outdated Show resolved Hide resolved
pkg/db/dto/git_provider.go Outdated Show resolved Hide resolved
pkg/gitprovider/types.go Outdated Show resolved Hide resolved
@bryans-go
Copy link
Contributor Author

bryans-go commented Oct 1, 2024

@Tpuljak
Done !
did all requested changes

@bryans-go
Copy link
Contributor Author

done

Signed-off-by: bryans-go <[email protected]>
Signed-off-by: bryans-go <[email protected]>
Signed-off-by: bryans-go <[email protected]>
@bryans-go bryans-go requested a review from Tpuljak October 2, 2024 12:34
pkg/git/service.go Show resolved Hide resolved
}

switch *providerConfig.SigningMethod {
case gitprovider.SigningMethodGPG:
Copy link
Member

Choose a reason for hiding this comment

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

How exactly did you test GPG signing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@Tpuljak you will need to specify what problem are you facing. I also faced some problems while testing
you can visit here for troubleshooting
https://docs.gitlab.com/ee/user/project/repository/signed_commits/gpg.html#troubleshooting

Copy link
Member

@Tpuljak Tpuljak Oct 2, 2024

Choose a reason for hiding this comment

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

@bryans-go you're supposed to tell us how to test this 😄

Please let us know how exactly you tested this and proof that it actually works.
The issue I'm having is that, inside the project, I can't sign with GPG because the secret key is missing.

Copy link
Contributor Author

@bryans-go bryans-go Oct 2, 2024

Choose a reason for hiding this comment

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

@Tpuljak
we will need to do some changes here

func generateSshConfigEntry(profileId, workspaceId, projectName, knownHostsPath string) (string, error) {
	daytonaPath, err := os.Executable()
	if err != nil {
		return "", err
	}

	tab := "\t"
	projectHostname := GetProjectHostname(profileId, workspaceId, projectName)

	config := fmt.Sprintf("Host %s\n"+
		tab+"User daytona\n"+
		tab+"StrictHostKeyChecking no\n"+
		tab+"UserKnownHostsFile %s\n"+
		tab+"ProxyCommand \"%s\" ssh-proxy %s %s %s\n"+
		tab+"ForwardAgent yes\n"+
		tab+"StreamLocalBindUnlink yes\n"+
		tab+"RemoteForward /home/daytona/.gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra\n\n",   // the 1000 is hardcoded we can make it dynamic
		projectHostname, knownHostsPath, daytonaPath, profileId, workspaceId, projectName)

	return config, nil
}

also after that

we need to export the public gpg key gpg --armor --export 44C255D0CE19BFF3 // gpg key id submitted by user. copy the full output
then daytona ssh
then gpg --import
paste the output here and then ctrl+d

this steps can be reduced to // if we want to code it

  1. ssh -R /home/daytona/.gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra -o StreamLocalBindUnlink=yes user@remote

2.Ensure the following directory on the remote exists
if no then mkdir -p /home/daytona/.gnupg

Import the public GPG key on the remote (if not done yet):

gpg --export <key-id> | ssh user@remote 'gpg --import' // one line command will need to edit if we want to go this way by automatically adding public gpg in the project
Now we can do the gpg signing flawlessly

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Contributor Author

@bryans-go bryans-go Oct 3, 2024

Choose a reason for hiding this comment

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

apiClient.GitProviderAPI.GetGitProviderForUrl(ctx, encodedUrl).Execute() what will be the encoded url and ctx . I mean how to get repo url and which file change I'm not able to conclude anything

Copy link
Member

Choose a reason for hiding this comment

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

The URL is the encoded Repository.Url of the project you are entering and ctx can be context.Background().

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Please suggest a way to get git provide config because ssh_file.go doesn't let me import apiclient. Without using apiclient what others things we can do to get git provider config

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Even after thinking so much and surfing through codebase I'm not able to find a good way to do this

Copy link
Member

Choose a reason for hiding this comment

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

That information should be passed into EnsureSshConfigEntryAdded as an argument by callers of the function.

E.g. the daytona ssh command should get the git provider from the API, check if it has set gpg signing, if so, it should pass the appropriate argument to OpenTerminalSsh that will then pass that to EnsureSshConfigEntryAdded.

@bryans-go
Copy link
Contributor Author

bryans-go commented Oct 3, 2024

To forward your GPG keys over SSH using Unix Domain Socket Forwarding, follow these steps:

1. Get the GPG Agent Socket Paths

On your local machine, get the socket paths using gpgconf:

gpgconf --list-dirs agent-socket // do on remote machine or dtn ssh
gpgconf --list-dirs agent-extra-socket //do on local machine

In my case, the output shows:

  • Agent socket on remote: /home/daytona/.gnupg/S.gpg-agent
  • Extra socket on local: /run/user/1000/gnupg/S.gpg-agent.extra

2. Forward GPG Agent Socket via SSH

Use SSH with the -R option to forward the local GPG socket to the remote machine.

Example:

ssh -R /home/remote-user/.gnupg/S.gpg-agent:/run/user/1000/gnupg/S.gpg-agent.extra -o StreamLocalBindUnlink=yes user@remote

#1146 (comment) see this too

Make sure the remote directory exists: /home/remote-user/.gnupg/.

3. Import the Public Key on the Remote Machine

GPG requires the public part of the key to verify signatures or encrypt data. You can import it by running:

gpg --export <key-id> | ssh user@remote 'gpg --import'

Replace <key-id> with your actual GPG key ID.

4. Test the Setup

After logging into the remote machine, check if the key is available using:

gpg --list-secret-keys

If the key is listed, the forwarding works, and you can now use your GPG keys on the remote server.

@Tpuljak Tpuljak marked this pull request as draft October 3, 2024 07:15
pkg/git/service.go Outdated Show resolved Hide resolved
pkg/git/service.go Outdated Show resolved Hide resolved
Signed-off-by: bryans-go <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Git commit signing
2 participants