[x]
):I have two users and an organization:
Cloning an private repository with user_1 works.
Trying to clone an organization's private repository with user_2, fails with the following message:
Cloning into 'my_repo'...
Gitea: Key access denied
Deploy key access denied: [key_id: 6, repo_id: 58]
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists
If I simply make the repository public, user_2 is able to clone it.
Could be that same key has added multiple times?
I don't think so. Would it cause this problem only on private repositories?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs during the next 2 weeks. Thank you for your contributions.
This maybe resolved? @Governa could you confirm that?
Not resolved, I have the same problem at v1.7. I can't clone a private repo with a deploy (read-only) rsa key, auth works but clone is denied.
Making it public it works.
And yes, key is duped but I can't select an already uploaded key for a new repo, GUI makes you recreate the key for every repo you need to clone.
I don't think so. Would it cause this problem only on private repositories?
Absolutely, duped key doesn't work in private repos, but there's no way to have no duplicated keys cause they are needed at every repo you need to clone.
Could you run Update the '.ssh/authorized_keys' file with Gitea SSH keys. (Not needed for the built-in SSH server.)
on Admin UI before you do that?
Have you deleted some public keys? It seems https://github.com/go-gitea/gitea/pull/5684 resolved a key deleted issue.
Did rebuild the Keys and it doesn't works. Its a bug, not happenning with internal ssh server, change to it and you can clone without problem.
Ok so that log message is coming from cmd/serv.go
:
// Check if this deploy key belongs to current repository.
has, err := private.HasDeployKey(key.ID, repo.ID)
if err != nil {
fail("Key access denied", "Failed to access internal api: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
if !has {
fail("Key access denied", "Deploy key access denied: [key_id: %d, repo_id: %d]", key.ID, repo.ID)
}
So it seems that in the original bug report the problem was that key 6 wasn't associated with repo 58.
@jorgefuertes is your error the same? That is it is basically:
Deploy key access denied: [key_id: x, repo_id: y]
If so could you check that you don't have two copies of the same key in the db and which repo key X is associated with. It shouldn't happen that two copies of the same keys end up with different IDs but I guess it's possible.
In terms of the difference between the builtin server vs. external they both use this code path in cmd/serv.go - the only difference is the determination of the keyid, so my suspicion is that this key has multiple IDs.
Certenly, that's the error, an yes, key are duped across different repos, because you can't select a previously uploaded key from another repo.
Beside the bug (normal user doesn't need to know about internal or external SSH server, or duped keys), I think I would love to have a common pubkey store, system or organization wide, to choose deploy keys for a project.
Thanks everyone.
This isn't an internal external SSH issue. The problem is the duplicated key id for the same key.
It's just that the external SSH and the internal SSH just have slightly different orders for choosing which key id matches a particularly key. There will be repos you can access when using the internal that you can't when using the external and vice versa.
Now on master it shouldn't be possible for you to have two deploy key IDs for the same deploy key content so what version are you running?
I'm running 1.7 right now but tried several versions before.
I don't have duped keys into the same repo, I want to make it clear. There are duped keys in a system wide view and that fails using __external__ SSH server.
I have no issue with __internal__ SSH server until now.
I wasn't saying that they're duped within the same repo.
It doesn't matter if the same key is used by different repos it should have the always have the same key id.
Somehow at least one repo with that key has got it to have a different key id (it may no longer have that wrong key id).
Now, according to the current master code that can't happen - so this must have happened in an earlier iteration. IIRC lunny may have committed a bug fix for this.
Now, it sounds like the majority of your repos are using the correct key id, so you're not seeing this in the internal SSH server case simply because of different ordering.
Ok, so how do fix this and interrogate this further?
Ok, if you're willing to look at the db. Go into your database and look at the deploy_key
table.
SELECT * FROM "deploy_key" WHERE repo_id=Y;
should tell you what the key_id should be - one of these keys will have the correct fingerprint for your key X but will have a different id Z
SELECT * FROM "deploy_key" WHERE key_id=X;
should tell you which repos have the wrong key id attached. Similarly key_id=Z
Assure yourself that the fingerprints and names for these deploy keys are the same.
Choose one of X or Z as the correct key_id K and wrong key_id W probably the lowest key_id should be K. Now you have two options:
You can try to get Gitea to clean up the situation itself. So if there are repos with the wrong key W attached, go in to Gitea and delete these keys, you should be able to add these again later. Don't re-add until all of the wrong ones are removed, probably you should remove all of the correct ones too to increase the chances that this is fixed once and for all. You should then be able to re add these keys once all of the old ones are removed. If that doesn't work then you'll have to do database hacking.
Hack the db. It's probably around a 50% chance that when you add the key back in to the repo, W instead of K will be written because I'm not sure how the public_key entry for W will get removed. If the above doesn't work or you're happy to just do some SQL hacking then...
SELECT * FROM public_key WHERE id = W OR id = K;
UPDATE deploy_key SET key_id = K WHERE key_id = W;
DELETE FROM public_key WHERE id = W;
If you can't access your db, or you're unable to translate that SQL to your db. You can look at the .ssh/authorized_keys
you should be able to compare the public key content for each line. In the command environment setting you will notice a key-X argument to the gitea serv command. That is the key id. If you compare you should see that there are likely two lines with the same public key content but different key ids. Now converting that key id back to the repository it's referring to is difficult without touching the db, but if there are two lines you definitely have a repository that is referring to the old key. You should be able to use the API to lookup the key, but even though I wrote that API I can't remember just now. But otherwise you should just delete all the deploy keys that match that public key from all repos. If you even miss one this will likely fail to fix your problem. That is I appreciate possibly a lot of work, hence the SQL I've provided.
Thank you very much for this complete explanation, I'll try it.
@zeripath I think maybe one of your recent PRs has resolved this.
Hi @lunny yeah my recent PRs should prevent this from happening in future.
Unfortunately they won't fix the poor users who have been bitten by these bugs in the past.
@jorgefuertes I think my fixes above are still the way to fix your broken state - hopefully that fixed things for you. On master and the 1.7 branch are comprehensive fixes for deployment key and public key constraints which should prevent this from ever happening again.
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs during the next 2 weeks. Thank you for your contributions.
I'm not able to reproduce this issue anymore. Solved