| name | maintainx-security-basics |
| description | Configure MaintainX API security, credential management, and access control.
Use when securing API keys, implementing access controls,
or hardening your MaintainX integration.
Trigger with phrases like "maintainx security", "maintainx api key security",
"secure maintainx", "maintainx credentials", "maintainx access control".
|
| allowed-tools | Read, Write, Edit, Bash(npm:*) |
| version | 1.0.0 |
| license | MIT |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
MaintainX Security Basics
Overview
Secure your MaintainX integration with proper credential management, access controls, and security best practices.
Prerequisites
- MaintainX account with admin access
- Understanding of environment variables
- Familiarity with secret management concepts
Security Checklist
Instructions
Step 1: Secure Credential Storage
import { SecretManagerServiceClient } from '@google-cloud/secret-manager';
interface SecureConfig {
maintainxApiKey: string;
maintainxOrgId?: string;
}
function loadFromEnv(): SecureConfig {
const apiKey = process.env.MAINTAINX_API_KEY;
if (!apiKey) {
throw new Error(
'MAINTAINX_API_KEY not set. ' +
'Set it as an environment variable or use a secret manager.'
);
}
return {
maintainxApiKey: apiKey,
maintainxOrgId: process.env.MAINTAINX_ORG_ID,
};
}
async function loadFromSecretManager(): Promise<SecureConfig> {
const client = new SecretManagerServiceClient();
const projectId = process.env.GCP_PROJECT_ID;
const [apiKeyVersion] = client.({
: ,
});
apiKey = apiKeyVersion.?.?.();
(!apiKey) {
();
}
{ : apiKey };
}
(): <> {
vault = ()({
: ,
: process..,
: process..,
});
secret = vault.();
{
: secret...,
};
}
(): <> {
env = process.. || ;
(env) {
:
();
:
();
:
();
}
}
Step 2: Git Security Configuration
# .gitignore - ALWAYS include these
# Environment files
.env
.env.*
!.env.example
# API keys and secrets
*.key
*.pem
secrets/
credentials/
# IDE and local config
.idea/
.vscode/settings.json
# Log files that might contain sensitive data
*.log
logs/
MAINTAINX_API_KEY=your-api-key-here
MAINTAINX_ORG_ID=optional-org-id
GCP_PROJECT_ID=your-gcp-project
VAULT_ADDR=https://vault.example.com
Step 3: Pre-commit Hook for Secrets Detection
#!/bin/bash
PATTERNS=(
'MAINTAINX_API_KEY\s*=\s*["\x27][a-zA-Z0-9_-]{20,}'
'mx_live_[a-zA-Z0-9]+'
'mx_test_[a-zA-Z0-9]+'
'Bearer\s+[a-zA-Z0-9_-]{20,}'
)
for pattern in "${PATTERNS[@]}"; do
if git diff --cached | grep -qE "$pattern"; then
echo "ERROR: Potential secret detected in commit!"
echo "Pattern: $pattern"
echo ""
echo "Remove the secret and use environment variables instead."
exit 1
fi
done
echo "Pre-commit security check passed."
chmod +x .git/hooks/pre-commit
Step 4: Input Validation
import { z } from 'zod';
const WorkOrderInputSchema = z.object({
title: z.string()
.min(1, 'Title is required')
.max(200, 'Title too long')
.regex(/^[^<>]*$/, 'Invalid characters in title'),
description: z.string()
.max(10000, 'Description too long')
.optional(),
priority: z.enum(['NONE', 'LOW', 'MEDIUM', 'HIGH']).optional(),
assetId: z.string()
.regex(/^[a-zA-Z0-9_-]+$/, 'Invalid asset ID format')
.optional(),
locationId: z.string()
.regex(/^[a-zA-Z0-9_-]+$/, 'Invalid location ID format')
.optional(),
dueDate: z.string()
.datetime()
.optional(),
});
= z.< >;
(): {
.(input);
}
(): {
sensitiveFields = [, , , ];
sanitized = { ...data };
( field sensitiveFields) {
(sanitized[field]) {
sanitized[field] = ;
}
}
sanitized;
}
{
() {
validatedInput = (input);
.(, (validatedInput));
..(validatedInput);
}
}
Step 5: Audit Logging
interface AuditEntry {
timestamp: string;
action: string;
resource: string;
resourceId?: string;
userId?: string;
ipAddress?: string;
success: boolean;
errorMessage?: string;
requestData?: any;
}
class AuditLogger {
private logs: AuditEntry[] = [];
log(entry: Omit<AuditEntry, 'timestamp'>) {
const fullEntry: AuditEntry = {
...entry,
timestamp: new Date().toISOString(),
requestData: entry.requestData
? sanitizeForLogging(entry.requestData)
: undefined,
};
this.logs.push(fullEntry);
console.log(`[AUDIT] on : `);
}
(: ): [] {
..( l. === resourceId);
}
}
auditLogger = ();
{
: ;
: ;
?: ;
() {
. = client;
. = auditLogger;
. = userId;
}
() {
{
result = ..(data);
..({
: ,
: ,
: result.,
: .,
: ,
: data,
});
result;
} (: ) {
..({
: ,
: ,
: .,
: ,
: error.,
: data,
});
error;
}
}
}
Step 6: API Key Rotation
async function rotateApiKey() {
console.log('=== MaintainX API Key Rotation ===\n');
console.log('1. Generate new API key:');
console.log(' - Go to Settings > Integrations');
console.log(' - Click "New Key" > "Generate Key"');
console.log(' - Copy the new key\n');
console.log('2. Update secret manager:');
console.log(' - GCP: gcloud secrets versions add maintainx-api-key --data-file=newkey.txt');
console.log(' - Vault: vault kv put secret/maintainx api_key=NEW_KEY\n');
console.log('3. Deploy application with new key');
console.log(' - kubectl rollout restart deployment/your-app');
console.log(' - Or trigger CI/CD pipeline\n');
console.log();
.();
.();
.();
.();
.();
.();
}
();
Step 7: Network Security
import https from 'https';
const secureAxiosConfig = {
baseURL: 'https://api.getmaintainx.com/v1',
timeout: 30000,
httpsAgent: new https.Agent({
rejectUnauthorized: true,
minVersion: 'TLSv1.2',
}),
headers: {
'Content-Type': 'application/json',
'User-Agent': 'YourApp/1.0.0',
},
};
Output
- Secure credential storage configured
- Git hooks preventing secret commits
- Input validation implemented
- Audit logging enabled
- Key rotation procedure documented
Security Checklist Verification
npm audit
git secrets --scan
npx eslint --rule 'no-hardcoded-credentials: error' src/
Resources
Next Steps
For production deployment, see maintainx-prod-checklist.