Add 14 Agent Skills for Mattermost OIDC plugin development workflows#20
Conversation
- Created comprehensive agent skills following VS Code Copilot and AgentSkills.io specification - Implemented 14 skills covering development, configuration, testing, deployment, and operations - Each skill includes YAML frontmatter, summary, detailed instructions, examples, and cross-references - Skills provide AI agents with domain knowledge for automated workflows and guidance - Added master README documenting all skills and usage patterns Co-authored-by: insoln <11380274+insoln@users.noreply.github.com>
Co-authored-by: insoln <11380274+insoln@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR implements a comprehensive set of 14 Agent Skills following VS Code Copilot and AgentSkills.io specifications to enable AI-assisted development for the Mattermost OIDC plugin. The skills cover the complete plugin lifecycle from development to production operations.
Changes:
- Added 14 Agent Skills organized into 4 categories (Development & Build, Configuration & Deployment, Testing & Validation, Operations & Support)
- Created master README with skill catalog, usage guide, and integration examples
- Added comprehensive summary document with metrics and completion report
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| AGENT_SKILLS_SUMMARY.md | Comprehensive summary of implementation with metrics and completion status |
| .github/skills/README.md | Master index with skill catalog, usage guide, and integration instructions |
| .github/skills/dev-environment/SKILL.md | Local development stack setup and management workflows |
| .github/skills/keycloak-setup/SKILL.md | Keycloak OIDC provider configuration procedures |
| .github/skills/plugin-build/SKILL.md | Go backend and React webapp build processes |
| .github/skills/plugin-install/SKILL.md | Plugin installation and configuration in Mattermost |
| .github/skills/oidc-flow-test/SKILL.md | OIDC authentication flow testing procedures |
| .github/skills/proxy-setup/SKILL.md | Reverse proxy configuration for automatic redirects |
| .github/skills/troubleshooting/SKILL.md | Diagnostic procedures and issue resolution |
| .github/skills/user-provisioning/SKILL.md | User management and role mapping configuration |
| .github/skills/security-audit/SKILL.md | Security best practices and audit procedures |
| .github/skills/observability/SKILL.md | Logging, metrics, and tracing configuration |
| .github/skills/config-migration/SKILL.md | Configuration migration between versions and environments |
| .github/skills/e2e-testing/SKILL.md | Playwright E2E test development and execution |
| .github/skills/health-check/SKILL.md | Component health validation and monitoring |
| .github/skills/release-management/SKILL.md | Release preparation and publishing workflows |
| # Or restore individual settings | ||
| mmctl config set PluginSettings.Plugins.com.mm.oidc.issuer_url "https://keycloak.example.com/realms/mattermost" | ||
| mmctl config set PluginSettings.Plugins.com.mm.oidc.client_id "mm-oidc" | ||
| mmctl config set PluginSettings.Plugins.com.mm.oidc.client_secret "$(vault kv get -field=secret secret/mm-oidc)" |
There was a problem hiding this comment.
This example passes the OIDC client secret directly on the command line to mmctl config set, which can expose the secret via shell history and process listings on multi-user systems. An attacker with local access could recover the client secret and impersonate the Mattermost OIDC client against the IdP or other environments using the same secret. Update the documentation to show a pattern that avoids placing secrets on the command line (for example, using mmctl ... --secret or another mechanism that reads the secret from stdin or a secure store).
| mmctl config set PluginSettings.Plugins.com.mm.oidc.client_secret "$(vault kv get -field=secret secret/mm-oidc)" | |
| # Restore client secret securely from Vault without placing it on the command line | |
| vault kv get -field=secret secret/mm-oidc \ | |
| | mmctl config set PluginSettings.Plugins.com.mm.oidc.client_secret --value-from-stdin |
There was a problem hiding this comment.
Fixed in commit b413a57. Updated both instances in the config-migration skill:
- Line 64: Now uses
vault kv get ... | mmctl config set ... --value-from-stdinto avoid shell history exposure - Line 150: Now uses temporary file with restricted permissions (chmod 600) instead of command substitution
This ensures client secrets are never exposed in shell history or process listings.
|
@copilot apply changes based on the comments in this thread убедись, что если в документации описан процесс, который используется агентом, то в агенте есть ссылка на эту документацию убедись, что в .github/copilot-instructions.md не дублируется информации, которая описана в скиллах. этот файл должен быть компактным |
…opilot-instructions - Fix command line secret exposure in config-migration skill - Use --value-from-stdin for mmctl to avoid shell history exposure - Use temporary file with restricted permissions for jq operations - Streamline copilot-instructions.md to avoid duplication with agent skills - Reduced from 163 to 104 lines (36% reduction) - Added reference to agent skills directory - Removed detailed workflow instructions now covered by skills - All skills already have proper documentation references Co-authored-by: insoln <11380274+insoln@users.noreply.github.com>
Changes applied in commit b413a57: ✅ Security fix: Fixed command line secret exposure in config-migration skill (addressed review comment) ✅ Documentation references: All skills already have proper documentation references in their "References" sections ✅ Streamlined copilot-instructions.md:
|
| # Create release | ||
| curl -X POST \ | ||
| -H "Authorization: token $GITHUB_TOKEN" \ | ||
| -H "Accept: application/vnd.github.v3+json" \ | ||
| https://api.github.com/repos/insoln/mm-oidc/releases \ | ||
| -d '{ | ||
| "tag_name": "v0.0.3", | ||
| "name": "v0.0.3", | ||
| "body": "Release notes here", | ||
| "draft": false, | ||
| "prerelease": false | ||
| }' | ||
|
|
||
| # Upload artifact | ||
| # (Use release upload URL from response) |
There was a problem hiding this comment.
The example curl command for creating a GitHub release passes GITHUB_TOKEN via an HTTP header in the command line (-H "Authorization: token $GITHUB_TOKEN"), which exposes the token in the process list to any user able to run ps on the host. An attacker with local access could read this token from the process arguments and use it to modify or take over the repository, including tampering with releases. Prefer using tooling that reads the token from environment or a secrets store without embedding it in the command line (for example, gh release with ${{ secrets.GITHUB_TOKEN }} in CI, or using a credential helper) so the token never appears in process arguments.
| # Create release | |
| curl -X POST \ | |
| -H "Authorization: token $GITHUB_TOKEN" \ | |
| -H "Accept: application/vnd.github.v3+json" \ | |
| https://api.github.com/repos/insoln/mm-oidc/releases \ | |
| -d '{ | |
| "tag_name": "v0.0.3", | |
| "name": "v0.0.3", | |
| "body": "Release notes here", | |
| "draft": false, | |
| "prerelease": false | |
| }' | |
| # Upload artifact | |
| # (Use release upload URL from response) | |
| # Create release via GitHub API using gh (auth handled by gh; no token in args) | |
| gh api \ | |
| --method POST \ | |
| -H "Accept: application/vnd.github+json" \ | |
| /repos/insoln/mm-oidc/releases \ | |
| -f tag_name="v0.0.3" \ | |
| -f name="v0.0.3" \ | |
| -f body="$(cat RELEASE_NOTES.md)" \ | |
| -F draft=false \ | |
| -F prerelease=false | |
| # Upload artifact | |
| gh release upload v0.0.3 build/plugins/mm-oidc.tar.gz |
There was a problem hiding this comment.
Fixed in commit 179e284. Replaced curl with gh CLI for GitHub API operations:
- Primary method: Uses
gh apiandgh release upload(no token in process args) - Alternative documented: If curl is required, use temp file with restricted permissions
This ensures GITHUB_TOKEN is never exposed in shell history or process listings.
| curl -X POST ${TOKEN_URL} \ | ||
| -d grant_type=authorization_code \ | ||
| -d client_id=mm-oidc \ | ||
| -d client_secret=<secret> \ | ||
| -d code=<code> \ | ||
| -d redirect_uri=https://chat.example.com/plugins/com.mm.oidc/callback |
There was a problem hiding this comment.
The troubleshooting example for manually exchanging an authorization code for tokens uses curl with -d client_secret=<secret>, which in real use encourages pasting the actual client secret directly into the command line. Placing the client secret in process arguments makes it visible via ps and similar tools to any local user, allowing them to recover the secret and impersonate the OIDC client. To avoid leaking the client secret via process listings, use an approach where curl reads the secret from stdin, a protected file, or a dedicated credential helper rather than passing it inline as a -d argument.
| curl -X POST ${TOKEN_URL} \ | |
| -d grant_type=authorization_code \ | |
| -d client_id=mm-oidc \ | |
| -d client_secret=<secret> \ | |
| -d code=<code> \ | |
| -d redirect_uri=https://chat.example.com/plugins/com.mm.oidc/callback | |
| # Store client secret in a protected file to avoid exposing it in process arguments: | |
| # echo -n 'your-real-client-secret' > client-secret.txt | |
| # chmod 600 client-secret.txt | |
| # | |
| # Then exchange the authorization code for tokens: | |
| curl -X POST "${TOKEN_URL}" \ | |
| -d grant_type=authorization_code \ | |
| -d client_id=mm-oidc \ | |
| -d code=<code> \ | |
| -d redirect_uri=https://chat.example.com/plugins/com.mm.oidc/callback \ | |
| --data-urlencode client_secret@"client-secret.txt" |
There was a problem hiding this comment.
Fixed in commit 179e284. Updated token exchange example to use secure pattern:
- Client secret stored in temp file with chmod 600
- Uses
--data-urlencode @fileto read from file (not command line) - Added cleanup step to remove temp file
This prevents client_secret from appearing in shell history or process listings.
|
@copilot apply changes based on the comments in this thread |
… process args - release-management: Replace curl with gh CLI for GitHub API to avoid token exposure - Primary method: Use 'gh api' and 'gh release upload' (no token in process args) - Alternative documented: Use temp file with restricted permissions if curl required - troubleshooting: Fix client_secret exposure in OIDC token exchange example - Use temp file with chmod 600 and --data-urlencode @file to read secret - Add cleanup step to remove temp file after use - Both fixes prevent secrets from appearing in shell history or process listings Co-authored-by: insoln <11380274+insoln@users.noreply.github.com>
Changes applied in commit 179e284: ✅ release-management: Fixed GITHUB_TOKEN exposure - replaced curl with All security vulnerabilities from the review have been addressed. Secrets are now handled securely throughout all agent skills. |
Agent Skills Implementation - COMPLETED ✅
All Requirements Met
Phase 1: Analysis & Planning
Phase 2: Skill Design
.github/skills/Phase 3: Implementation
Phase 4: Validation
Phase 5: Documentation
Phase 6: Security Review & Fixes
Security Fixes Applied
Round 1 (commit b413a57)
--value-from-stdinand temp filesRound 2 (this commit)
ghCLI to avoid GITHUB_TOKEN in process argsgh apiandgh release upload--data-urlencode @fileAll secrets now handled securely without exposure in shell history or process listings.
Deliverables
14 Agent Skills Created (All Secure)
Development & Build (4):
Configuration & Deployment (4):
5. keycloak-setup (134 lines) - IdP configuration
6. plugin-install (353 lines) - Plugin deployment
7. proxy-setup (376 lines) - Reverse proxy
8. config-migration (325 lines) - Configuration management ✨ Security fixed
Testing & Validation (3):
9. oidc-flow-test (398 lines) - Auth flow testing
10. health-check (297 lines) - Health validation
11. security-audit (385 lines) - Security review
Operations & Support (3):
12. troubleshooting (289 lines) - Diagnostics ✨ Security fixed
13. user-provisioning (208 lines) - User management
14. observability (352 lines) - Monitoring
Documentation
.github/skills/README.md(264 lines) - Master index.github/copilot-instructions.md(104 lines) - Streamlined instructionsAGENT_SKILLS_SUMMARY.md(368 lines) - Implementation reportAll requirements completed. Skills are production-ready, secure, and follow security best practices.
Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.