Skip to content
Open
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e2dbabe
Add Storage Programs data column to GCR
Oct 10, 2025
b0b062f
Implement Storage Program handlers and validators (Phase 2)
Oct 10, 2025
1bbed30
feat: Phase 3 - HandleGCR integration for Storage Programs
Oct 10, 2025
7a5062f
feat: Phase 4 - Endpoint integration for Storage Programs
Oct 10, 2025
28412a5
feat: Phase 6 - RPC query endpoint for Storage Programs
Oct 10, 2025
db614cc
docs: Add Storage Programs documentation and fix critical bugs
Oct 10, 2025
fdf1a87
updated memories and sdk bump
Oct 10, 2025
06d6941
removed useless files
Oct 10, 2025
9267dce
untracked spec file
Oct 10, 2025
23f4a74
ignored files
Oct 10, 2025
a723f82
Update src/libs/network/routines/transactions/handleStorageProgramTra…
tcsenpai Oct 10, 2025
716d3c1
Update src/libs/blockchain/gcr/handleGCR.ts
tcsenpai Oct 10, 2025
33842c6
Update src/libs/network/endpointHandlers.ts
tcsenpai Oct 10, 2025
224a8fe
Fix Storage Programs code review issues
Oct 10, 2025
2e46a70
Fix Storage Programs operation-specific validation logic
Oct 11, 2025
ce786c4
better comments
Oct 11, 2025
c3f69e0
reviewed pr
Oct 11, 2025
2bc81d8
updated memories
Oct 11, 2025
3dbe737
bump and fixed types
Oct 11, 2025
6690f9b
Improve code clarity for Storage Programs implementation
Oct 11, 2025
d6135a0
safeguarded storage calls
Oct 11, 2025
d427685
Fix Storage Program validation error handling and size calculation cl…
Oct 11, 2025
0f79151
updated memories
Oct 11, 2025
45142fc
updated gitignore
Oct 23, 2025
ba72d0e
fix: strengthen Storage Programs input validation and access control
Oct 23, 2025
325ba7d
chore: bump @kynesyslabs/demosdk to 2.4.24
Oct 23, 2025
bf84c60
ignores
Nov 3, 2025
da5c981
Validate storage program access control inputs
Nov 3, 2025
0c72430
Fix copy-paste error in crosschainOperation error messages
claude Nov 4, 2025
32a34b5
Merge storage branch with bugfix into review branch
claude Nov 4, 2025
75c8209
Merge pull request #491 from kynesyslabs/claude/review-branches-011CU…
tcsenpai Nov 4, 2025
3912cfa
Sync AGENTS.md from testnet
Dec 6, 2025
370fa33
beads init
Dec 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,5 @@ docs/src
src/features/bridges/EVMSmartContract/docs
src/features/bridges/LiquidityTank_UserGuide.md
local_tests
docs/storage_features
STORAGE_PROGRAMS_SPEC.md
126 changes: 126 additions & 0 deletions .serena/memories/session_2025-10-11_storage_programs_review_fixes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
# Storage Programs Code Review Fixes Session

## Session Summary
**Date**: 2025-10-11
**Branch**: storage
**Focus**: Addressing critical code review feedback for Storage Programs implementation

## Commits Created

### Commit 1: `224a8fe9` - Initial Code Review Fixes
**Files Modified**: 5 files (+70, -56 lines)

1. **CRITICAL: Access Control Bypass Fixed** (manageNodeCall.ts, server_rpc.ts)
- Added `sender?: string` parameter to manageNodeCall()
- Pass authenticated caller from RPC server headers
- Enforce access control in getStorageProgram endpoint
- Return 403 Forbidden without data leakage
- Private/restricted programs now properly protected

2. **MAJOR: Logger Fix** (handleGCR.ts:527)
- Fixed `log.error("[StorageProgram] Error applying edit:", error)`
- Embedded error message and stack trace in single string
- Prevents TypeScript type error (second param expects boolean)

3. **MAJOR: JSONB Index Removed** (GCR_Main.ts)
- Removed `@Index("idx_gcr_main_data_gin")` decorator
- Storage Programs only use primary key lookups
- Avoids PostgreSQL B-tree rejection on JSONB
- No GIN index needed for current query patterns

### Commit 2: `2e46a704` - Operation Validation Fixes
**Files Modified**: 2 files (+37, -12 lines)

1. **CRITICAL: Validation Guard Added** (handleGCR.ts:324-329)
- Added `context.data.variables` validation
- Prevents runtime error before unsafe access
- Clear error message returned

2. **CRITICAL: Operation-Specific Logic Fixed** (handleGCR.ts:339-406)
- **CREATE**: Requires account does NOT exist
- **WRITE/UPDATE/DELETE**: Requires account DOES exist
- Fixed broken non-CREATE operations
- Moved CREATE into operation-specific branch
- Fixed unreachable code issue

## Key Technical Decisions

### Access Control Architecture
- Caller identity from RPC headers (`"identity"` header)
- Validation using `validateStorageProgramAccess()` function
- Access modes: private, public, restricted, deployer-only
- 401 for missing auth, 403 for denied access

### Storage Program Query Pattern
```typescript
// All queries use primary key lookup
const storageProgram = await gcrRepo.findOne({
where: { pubkey: storageAddress } // Uses primary key index
})
// Then access JSONB in JavaScript
if (storageProgram.data.metadata.deployer === sender) { ... }
```

### Operation Flow
1. **CREATE**: Validate non-existence → Create account → Save → Return success
2. **WRITE**: Validate existence → Check access → Merge data → Validate size → Save
3. **UPDATE_ACCESS_CONTROL**: Validate existence → Check deployer → Update metadata
4. **DELETE**: Validate existence → Check deployer → Delete program

## Patterns Discovered

### Error Handling Pattern
```typescript
log.error(`[Context] Error: ${error instanceof Error ? `${error.message}\nStack: ${error.stack || 'N/A'}` : String(error)}`)
```

### Validation Guard Pattern
```typescript
if (!context.operation) return { success: false, message: "..." }
if (!context.data) return { success: false, message: "..." }
if (!context.data.variables) return { success: false, message: "..." }
// Safe to access context.data.variables
```

### Operation-Specific Existence Pattern
```typescript
if (operation === "CREATE") {
if (account) return { success: false, message: "Already exists" }
// Create logic
return { success: true, message: "Created" }
}
// For all other operations
if (!account) return { success: false, message: "Does not exist" }
// Update/delete logic
```

## Files Modified Summary

1. **src/libs/network/manageNodeCall.ts**
- Added sender parameter
- Added access control enforcement in getStorageProgram

2. **src/libs/network/server_rpc.ts**
- Pass sender to manageNodeCall

3. **src/libs/blockchain/gcr/handleGCR.ts**
- Fixed logger error call
- Added validation guards
- Fixed operation-specific existence logic

4. **src/libs/blockchain/validators/validateStorageProgramAccess.ts**
- Fixed duplicate if statement
- Updated validateCreateAccess comment

5. **src/model/entities/GCRv2/GCR_Main.ts**
- Removed unnecessary JSONB index

## Quality Verification
- All changes verified with `bun run lint:fix`
- No new ESLint errors introduced
- All errors in unrelated test files only

## Next Steps
- Monitor for any access control edge cases in production
- Consider adding metrics for storage program operations
- Potential future optimization: GIN index if JSONB queries added
121 changes: 121 additions & 0 deletions .serena/memories/storage_programs_access_control_patterns.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Storage Programs Access Control Patterns

## Access Control Implementation

### RPC Endpoint Security
**File**: `src/libs/network/manageNodeCall.ts`

```typescript
// Caller authentication required
if (!sender) {
response.result = 401
response.response = { error: "Caller address required for storage access" }
break
}

// Access control validation
const accessCheck = validateStorageProgramAccess(
"READ_STORAGE",
sender,
storageProgram.data,
)

if (!accessCheck.success) {
response.result = 403
response.response = { error: accessCheck.error || "Access denied" }
break
}
```

### Access Control Modes

**private / deployer-only**:
- Only deployer can read and write
- Most restrictive mode

**public**:
- Anyone can read
- Only deployer can write
- Good for public datasets

**restricted**:
- Only deployer or allowlisted addresses
- Configured via allowedAddresses array
- Good for shared team storage

### Validator Logic
**File**: `src/libs/blockchain/validators/validateStorageProgramAccess.ts`

```typescript
const isDeployer = requestingAddress === deployer

// Admin operations always require deployer
if (operation === "UPDATE_ACCESS_CONTROL" || operation === "DELETE_STORAGE_PROGRAM") {
return isDeployer ? { success: true } : { success: false, error: "..." }
}

// Mode-specific rules
switch (accessControl) {
case "private":
case "deployer-only":
return isDeployer ? { success: true } : { success: false }

case "public":
if (operation === "READ_STORAGE") return { success: true }
if (operation === "WRITE_STORAGE") {
return isDeployer ? { success: true } : { success: false }
}

case "restricted":
if (isDeployer || allowedAddresses.includes(requestingAddress)) {
return { success: true }
}
return { success: false }
}
```

### Authentication Flow

1. **RPC Request** → Headers contain `"identity"` field
2. **Server Validation** → `validateHeaders()` verifies signature
3. **Extract Sender** → `sender = headers.get("identity")`
4. **Pass to Handler** → `manageNodeCall(payload, sender)`
5. **Enforce Access** → `validateStorageProgramAccess(operation, sender, data)`
6. **Return 403/401** → Appropriate error without data leakage

### Security Considerations

**Never leak data on denial**:
```typescript
// ✅ Good - no data in error response
response.response = { error: "Access denied" }

// ❌ Bad - leaks metadata
response.response = { error: "Access denied", metadata: program.metadata }
```

**Always validate sender**:
```typescript
// ✅ Good - check sender exists
if (!sender) return 401

// ❌ Bad - assume sender exists
const accessCheck = validateStorageProgramAccess(operation, sender, data)
```

## Integration Points

### Transaction Handler
**File**: `src/libs/network/routines/transactions/handleStorageProgramTransaction.ts`

- Queues GCR edits with sender context
- Access validation happens in HandleGCR.applyStorageProgramEdit()
- Sender included in context for deferred validation

### GCR Handler
**File**: `src/libs/blockchain/gcr/handleGCR.ts`

- Receives sender from transaction context
- Validates access before applying edits
- Returns error if access denied
- No state changes on validation failure
Loading