mirror of
https://github.com/tiennm99/goclaw.git
synced 2026-10-14 16:17:25 +00:00
feat(cli-credentials): add agent-scoped git credentials
This commit is contained in:
1 parent
e6242dbbbc
commit
994acfe3a4
47 files changed
+2152
-113
No files matched your search
@@ -381,8 +381,6 @@ func (s *SQLiteSecureCLIStore) LookupByBinary(ctx context.Context, binaryName st
|
||||
|
||||
var args []any
|
||||
|
||||
query := `SELECT ` + selectCols
|
||||
|
||||
// Project user-credential columns (encrypted_env + credential_type + host_scope).
|
||||
// When userID is empty we cannot reference uc_user.* — emit NULL placeholders
|
||||
// so the scan column count stays stable.
|
||||
@@ -390,10 +388,17 @@ func (s *SQLiteSecureCLIStore) LookupByBinary(ctx context.Context, binaryName st
|
||||
hasUserJoinNoAgent := userID != "" && agentID == nil
|
||||
|
||||
if hasUserJoin || hasUserJoinNoAgent {
|
||||
query += `, uc_user.encrypted_env AS user_env, uc_user.credential_type AS user_cred_type, uc_user.host_scope AS user_host_scope FROM secure_cli_binaries b`
|
||||
selectCols += `, uc_user.encrypted_env AS user_env, uc_user.credential_type AS user_cred_type, uc_user.host_scope AS user_host_scope`
|
||||
} else {
|
||||
query += `, NULL AS user_env, NULL AS user_cred_type, NULL AS user_host_scope FROM secure_cli_binaries b`
|
||||
selectCols += `, NULL AS user_env, NULL AS user_cred_type, NULL AS user_host_scope`
|
||||
}
|
||||
if agentID != nil {
|
||||
selectCols += `, ac.encrypted_env AS agent_env, ac.credential_type AS agent_cred_type, ac.host_scope AS agent_host_scope`
|
||||
} else {
|
||||
selectCols += `, NULL AS agent_env, NULL AS agent_cred_type, NULL AS agent_host_scope`
|
||||
}
|
||||
|
||||
query := `SELECT ` + selectCols + ` FROM secure_cli_binaries b`
|
||||
|
||||
// LEFT JOIN agent grant
|
||||
if agentID != nil {
|
||||
@@ -402,6 +407,14 @@ func (s *SQLiteSecureCLIStore) LookupByBinary(ctx context.Context, binaryName st
|
||||
} else {
|
||||
query += ` LEFT JOIN secure_cli_agent_grants g ON 0`
|
||||
}
|
||||
if agentID != nil {
|
||||
query += ` LEFT JOIN secure_cli_agent_credentials ac ON ac.binary_id = b.id AND ac.agent_id = ?`
|
||||
args = append(args, *agentID)
|
||||
if !isCross {
|
||||
query += ` AND ac.tenant_id = ?`
|
||||
args = append(args, tid)
|
||||
}
|
||||
}
|
||||
|
||||
// LEFT JOIN user credentials (only when we project uc_user.*)
|
||||
if hasUserJoin || hasUserJoinNoAgent {
|
||||
@@ -457,6 +470,8 @@ func (s *SQLiteSecureCLIStore) scanRowWithGrantAndUserEnv(row *sql.Row) (*store.
|
||||
var grantEncEnv []byte
|
||||
var userEnv []byte
|
||||
var userCredType, userHostScope *string
|
||||
var agentEnv []byte
|
||||
var agentCredType, agentHostScope *string
|
||||
var createdAt, updatedAt sqliteTime
|
||||
|
||||
err := row.Scan(
|
||||
@@ -466,6 +481,7 @@ func (s *SQLiteSecureCLIStore) scanRowWithGrantAndUserEnv(row *sql.Row) (*store.
|
||||
&b.Enabled, &b.CreatedBy, &b.AdapterName, &createdAt, &updatedAt,
|
||||
&grantDenyArgs, &grantDenyVerbose, &grantTimeout, &grantTips, &grantEnabled, &grantID, &grantEncEnv,
|
||||
&userEnv, &userCredType, &userHostScope,
|
||||
&agentEnv, &agentCredType, &agentHostScope,
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
@@ -506,24 +522,46 @@ func (s *SQLiteSecureCLIStore) scanRowWithGrantAndUserEnv(row *sql.Row) (*store.
|
||||
}
|
||||
grant.TimeoutSeconds = grantTimeout
|
||||
grant.Tips = grantTips
|
||||
if len(grantEncEnv) > 0 && s.encKey != "" {
|
||||
if decrypted, err := crypto.Decrypt(string(grantEncEnv), s.encKey); err == nil {
|
||||
grant.EncryptedEnv = []byte(decrypted)
|
||||
if len(grantEncEnv) > 0 {
|
||||
if s.encKey != "" {
|
||||
if decrypted, err := crypto.Decrypt(string(grantEncEnv), s.encKey); err == nil {
|
||||
grant.EncryptedEnv = []byte(decrypted)
|
||||
}
|
||||
} else {
|
||||
grant.EncryptedEnv = grantEncEnv
|
||||
}
|
||||
}
|
||||
b.MergeGrantOverrides(grant)
|
||||
}
|
||||
|
||||
// Decrypt per-user env
|
||||
if len(userEnv) > 0 && s.encKey != "" {
|
||||
if decrypted, err := crypto.Decrypt(string(userEnv), s.encKey); err == nil {
|
||||
b.UserEnv = []byte(decrypted)
|
||||
if len(userEnv) > 0 {
|
||||
if s.encKey != "" {
|
||||
if decrypted, err := crypto.Decrypt(string(userEnv), s.encKey); err == nil {
|
||||
b.UserEnv = []byte(decrypted)
|
||||
}
|
||||
} else {
|
||||
b.UserEnv = userEnv
|
||||
}
|
||||
}
|
||||
|
||||
// Typed-credential metadata from the joined user-credential row.
|
||||
b.UserCredentialType = userCredType
|
||||
b.UserHostScope = userHostScope
|
||||
if len(b.UserEnv) > 0 || userCredType != nil || userHostScope != nil {
|
||||
b.SetEffectiveCredential(b.UserEnv, userCredType, userHostScope, "user", "")
|
||||
}
|
||||
if len(agentEnv) > 0 || agentCredType != nil || agentHostScope != nil {
|
||||
decrypted := agentEnv
|
||||
if len(agentEnv) > 0 && s.encKey != "" {
|
||||
if d, err := crypto.Decrypt(string(agentEnv), s.encKey); err == nil {
|
||||
decrypted = []byte(d)
|
||||
}
|
||||
}
|
||||
if b.CredentialSource == "" {
|
||||
b.SetEffectiveCredential(decrypted, agentCredType, agentHostScope, "agent", "")
|
||||
}
|
||||
}
|
||||
|
||||
return &b, nil
|
||||
}
|
||||
@@ -533,7 +571,7 @@ func (s *SQLiteSecureCLIStore) applyContextSecureCLI(ctx context.Context, b *sto
|
||||
if len(scopes) == 0 || b == nil {
|
||||
return b, nil
|
||||
}
|
||||
hasUserCredential := len(b.UserEnv) > 0 || b.UserCredentialType != nil || b.UserHostScope != nil
|
||||
hasUserCredential := b.CredentialSource == "user" || len(b.UserEnv) > 0 || b.UserCredentialType != nil || b.UserHostScope != nil
|
||||
disabledByContext := false
|
||||
for _, scope := range scopes {
|
||||
grants, err := s.ListContextGrantsForScope(ctx, scope)
|
||||
@@ -572,9 +610,7 @@ func (s *SQLiteSecureCLIStore) applyContextSecureCLI(ctx context.Context, b *sto
|
||||
continue
|
||||
}
|
||||
if !hasUserCredential {
|
||||
b.UserEnv = creds.EncryptedEnv
|
||||
b.UserCredentialType = creds.CredentialType
|
||||
b.UserHostScope = creds.HostScope
|
||||
b.SetEffectiveCredential(creds.EncryptedEnv, creds.CredentialType, creds.HostScope, "context", scope.ScopeType+":"+scope.ScopeKey)
|
||||
} else {
|
||||
b.EncryptedEnv = creds.EncryptedEnv
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user