requireVaultMember checks that the session has member+ access to the vault. For scoped sessions: requires sess.VaultRole is "member" or "admin". For instance-level sessions: checks the unified vault_grants table.
(w http.ResponseWriter, r *http.Request, vaultID string)
| 653 | // For scoped sessions: requires sess.VaultRole is "member" or "admin". |
| 654 | // For instance-level sessions: checks the unified vault_grants table. |
| 655 | func (s *Server) requireVaultMember(w http.ResponseWriter, r *http.Request, vaultID string) (*Actor, error) { |
| 656 | sess := sessionFromContext(r.Context()) |
| 657 | if sess == nil { |
| 658 | jsonError(w, http.StatusForbidden, "Authentication required") |
| 659 | return nil, fmt.Errorf("no session") |
| 660 | } |
| 661 | |
| 662 | // Scoped session: check vault_role from session. |
| 663 | if sess.VaultID != "" { |
| 664 | if sess.VaultID != vaultID { |
| 665 | jsonError(w, http.StatusForbidden, "Session not authorized for this vault") |
| 666 | return nil, fmt.Errorf("vault mismatch") |
| 667 | } |
| 668 | if !roleSatisfies(sess.VaultRole, "member") { |
| 669 | jsonError(w, http.StatusForbidden, "Member role required") |
| 670 | return nil, fmt.Errorf("insufficient role: %s", sess.VaultRole) |
| 671 | } |
| 672 | return nil, nil |
| 673 | } |
| 674 | |
| 675 | // Instance-level session: check vault grant and role. |
| 676 | actor, err := s.actorFromSession(r.Context(), sess) |
| 677 | if err != nil { |
| 678 | jsonError(w, http.StatusForbidden, "Invalid session") |
| 679 | return nil, err |
| 680 | } |
| 681 | |
| 682 | role, err := s.store.GetVaultRole(r.Context(), actor.ID, vaultID) |
| 683 | if err != nil { |
| 684 | jsonError(w, http.StatusForbidden, "No access to this vault") |
| 685 | return nil, fmt.Errorf("no vault grant") |
| 686 | } |
| 687 | if !roleSatisfies(role, "member") { |
| 688 | jsonError(w, http.StatusForbidden, "Member role required") |
| 689 | return nil, fmt.Errorf("insufficient role: %s", role) |
| 690 | } |
| 691 | return actor, nil |
| 692 | } |
| 693 | |
| 694 | // assertBuiltinCredentialStore writes 409 and returns false when the vault |
| 695 | // is external-backed. Fails closed (500) on transient lookup errors. |
no test coverage detected