یک Pipeline میتواند هفت Job امنیتی سبز، صفر Finding با Severity بالا و Badge موفق داشته باشد، اما Artifactی را منتشر کند که SCA و DAST روی آن اجرا نشدهاند. سبزبودن Job فقط میگوید Process با Exit code موردانتظار تمام شده؛ نمیگوید Subject درست، Ruleset جاری، Vulnerability database تازه، Evidence کامل، Runner قابلاعتماد یا Exception معتبر بوده است.
DevSecOps با افزودن چند Scanner به YAML ساخته نمیشود. امنیت باید از Threat/Risk و Requirement به Control قابلردیابی برسد؛ Control روی Source/Artifact/Environment معین اجرا شود؛ Evidence نسخهدار تولید کند؛ Policy نتیجه را به Allow/Hold/Review/Exception ترجمه کند؛ و Artifact همان زنجیره با Provenance معتبر Promote شود. این مقاله Contract این حلقه را طراحی میکند—بدون وعدهٔ «نرمافزار امن»، کاهش قطعی هزینه یا اثبات خودکار Compliance.
مسیر کوتاه: DevSecOps قابلبازبینی در هشت گام
| گام | پرسش | خروجی حداقلی |
|---|---|---|
| Context | چه محصول/معماری/داده/تهدیدی داریم؟ | Threat/Risk/Requirement registry |
| Control | کدام کنترل کدام Risk را بررسی یا کاهش میدهد؟ | Control ID + objective |
| Bind | روی کدام Source/Commit/Artifact/Environment؟ | Immutable identities |
| Execute | با کدام Tool/Rule/DB/Runner؟ | Execution manifest |
| Interpret | Result، Finding، Error و Unknown چه معنایی دارند؟ | Normalized outcomes |
| Decide | Policy و Authority چه میگویند؟ | ALLOW/HOLD/REVIEW/EXCEPTION |
| Promote | همان Artifact با Signature/Provenance جابهجا شد؟ | Promotion attestation |
| Respond | پس از انتشار چه چیزی کشف/مهار/اصلاح میشود؟ | Detection/Response/Retest loop |
اگر تیم کوچک است، همهٔ کنترلها را همزمان اضافه نکند. یک Risk پراثر، یک مسیر Artifact و چند کنترل مکمل را انتخاب کند؛ Evidence و Exception را ببندد؛ سپس Coverage را گسترش دهد. «همهچیز را اسکن کنیم» بدون Context و ظرفیت Triage، فقط صف هشدار میسازد.
DevSecOps چیست و چه چیزی نیست؟
DevSecOps نامی برای واردکردن Practiceهای امنیتی به شیوهٔ توسعه، Build، Delivery/Deployment و Operation است. تعریف واحدِ اجباری، Stageهای جهانی یا Stack استانداردی ندارد. Automation مفید است، اما Threat modeling، Secure design/review، Penetration testing، Risk decision، Incident response و Human judgment را حذف نمیکند.
| برداشت نادرست | مرز دقیقتر |
|---|---|
| DevSecOps = خرید SAST/SCA/DAST | Tool فقط یک Control implementation با Coverage و limitation است. |
| Shift-left = همهٔ تستها در Commit | Feedback زودهنگام + کنترلهای right-time/right-context و runtime response |
| Pipeline سبز = امن | فقط اجرای تعریفشده موفق بوده؛ adequacy و absence of vulnerability ثابت نیست. |
| Shared responsibility = همه تصمیمگیرند | مشارکت مشترک با Decision right و escalation صریح |
| Gate = Release authority | Policy input؛ Release/Risk acceptance طبق Governance |
| Evidence = Compliance | یک ورودی محدود برای ارزیابی requirement معین |
منابع رسمی چگونه باید استفاده شوند؟
- NIST SP 800-218 SSDF 1.1 چهار گروه Prepare the Organization، Protect the Software، Produce Well-Secured Software و Respond to Vulnerabilities را با Practice/Taskهای سطحبالا ارائه میکند. Implementation exampleها الزامی، کامل یا دارای ترتیب اهمیت نیستند و باید با Context تطبیق یابند.
- NIST SP 800-204D راهبردهای زنجیرهٔ تأمین در CI/CD و مفاهیم Artifact، Attestation، Provenance، SBOM و Pipeline را توضیح میدهد؛ دامنهٔ آن بهخصوص معماری Cloud-native است و جای Risk assessment سازمان نیست.
- OWASP CI/CD Security Cheat Sheet خود Pipeline را Asset حساس میبیند و روی SCM، runner، IAM، Secret، third-party، integrity و logging تمرکز دارد؛ Checklist آن اثبات امنیت یا Compliance نیست.
- SLSA Provenance v1.2 اطلاعات قابلبررسی دربارهٔ اینکه Artifact کجا، چه زمان و چگونه تولید شده را مدل میکند؛ وجود Provenance بهتنهایی صحت Source، نبود Vulnerability یا اعتماد به Builder را اثبات نمیکند.
NIST SSDF نقشهٔ Stage اجباری نیست
SSDF میگوید Practiceهای توسعهٔ امن باید در SDLC موجود ادغام شوند و سازمان واژگان مبهمی مانند well-secured، sensitive data و نام Environmentها را برای Context خود تعریف کند. ترتیب جدول SSDF، توالی اجرا یا اولویت نیست. بنابراین نسبتدادن SAST فقط به Commit، SCA فقط به Build و DAST فقط به Test یک طراحی ممکن است، نه قانون NIST.
| گروه SSDF | پرسش محلی | Evidence نمونه | محدودیت |
|---|---|---|---|
| PO | Requirement/role/toolchain آماده است؟ | policy/training/environment records | حضور سند = اثربخشی نیست |
| PS | Source/Artifact از tamper محافظت میشود؟ | access/signature/provenance | integrity ≠ security adequacy |
| PW | Riskها در design/build/verification دیده میشوند؟ | trace/control/evidence | scanner coverage محدود است |
| RV | Vulnerability باقیمانده چگونه دریافت/اصلاح میشود؟ | intake/triage/advisory/retest | صرف SLA علت را رفع نمیکند |
مالکیت این مقاله: Security Control Contract
Threat / Asset / Abuse Case / Requirement -> Security Risk -> Control Objective -> Control Implementation -> Stage + Subject + Runner -> Evidence + Result + Limitation -> Policy Evaluation -> Decision | Exception | Escalation -> Immutable Artifact Promotion -> Runtime Detection / Response -> Remediation / Retest / Learning
این مقاله «کدام ابزار بهتر است» را مالک نیست. مقایسهٔ SAST/DAST/SCA و ابزارها در راهنمای ابزارهای تست امنیت و Coverage/Triage/Retest عملی آنها در عملیاتیسازی Portfolio ابزارهای AppSec آمده است. اینجا Interface میان Risk، کنترل، هویت، Evidence، Policy و Promotion موضوع اصلی است.
Baseline خط لوله را پیش از Result قفل کنید
| هویت | نمونه | خطای رایج |
|---|---|---|
| Product/Service | CHECKOUT-SYN | نام عمومی «backend» |
| Repository/Commit | repo://checkout-syn / C17 | branch mutable |
| Pipeline definition | PIPE-v4 | YAML بدون digest/revision |
| Security policy | SEC-POL-v4 | threshold در script پنهان |
| Threat model | TM-v3 | نسخهٔ طراحی اولیه |
| Build run | BUILD-R17 | job name |
| Artifact digest | sha256:ART17 | tag `latest` |
| SBOM/Provenance | sha256:SBOM17/PROV17 | فایل بدون hash/binding |
| Environment | ENV-SEC-7 | «staging» نامشخص |
| Vulnerability DB cutoff | 2026-08-12T06:00Z | «up to date» بدون زمان |
pipelineBaseline: product: CHECKOUT-SYN repository: repo://checkout-syn commit: C17 pipelineDefinition: PIPE-v4 securityPolicy: SEC-POL-v4 threatModel: TM-v3 buildRun: BUILD-R17 artifactDigest: sha256:ART17 sbomDigest: sha256:SBOM17 provenanceDigest: sha256:PROV17 environment: ENV-SEC-7 vulnerabilityDbCutoff: 2026-08-12T06:00:00Z
Threat و Requirement قبل از Scanner میآیند
Scanner فقط Patternهایی را که Engine و Ruleset میشناسند روی Subject قابلمشاهده بررسی میکند. Business-logic abuse، trust boundary، privilege path، data misuse یا supply-chain manipulation ممکن است با یک ابزار عمومی دیده نشود. Asset، actor، entry point، trust boundary، abuse case، impact، assumption و security requirement را پیش از انتخاب Control ثبت کنید.
| Risk | Control objective | Control mix | چیزی که باقی میماند |
|---|---|---|---|
| Secret در Source | پیشگیری/کشف credential material | pre-commit + history scan + rotation | entropy false positive/encoded secret |
| Dependency آسیبپذیر | شناخت component/exposure | lock/SBOM/SCA/VEX/reachability review | unknown CVE/config context |
| Authorization bypass | Policy enforcement across roles | design review + negative regression + DAST | unmodeled role/path |
| Pipeline poisoning | جلوگیری از untrusted privileged execution | review/isolation/least privilege/pinning | builder/platform compromise |
| Artifact substitution | Source-to-release integrity | digest/signature/provenance/promotion | trusted-but-vulnerable build |
Control Registry: از Risk به Evidence
securityControl: id: CTRL-SCA-04 riskRefs: [R-SUPPLY-02] objective: identify declared components and known-vulnerability signals subjectType: immutable artifact + bound SBOM stage: build-verification implementation: scanner-family-sca toolVersion: 3.1.0 rulesetPolicy: SCA-P4 dataSourceCutoff: 2026-08-12T06:00:00Z requiredEvidence: normalized report + raw digest + execution manifest outcomes: PASS | FINDING | ERROR | INCONCLUSIVE | NOT_APPLICABLE limitation: known data/source/component-resolution only policyRef: SEC-POL-v4 owner: appsec-capability-a
Control owner مسئول طراحی/نگهداری کنترل است؛ Service owner مسئول remediation محلی؛ Risk owner صاحب پذیرش Risk در حدود اختیار؛ Platform owner صاحب Runner/Pipeline؛ و Release authority طبق Governance تصمیم میگیرد. «امنیت مسئولیت همه است» بدون این تفکیک، Exception و incident را بیصاحب میکند.
SAST چه میبیند و چه نمیبیند؟
SAST معمولاً Source یا representationهای میانی را بدون اجرای سامانه تحلیل میکند. نتیجه به زبان/framework، build resolution، flow sensitivity، configuration، rule coverage، sanitizer model و reachability وابسته است. یک Finding میتواند Weakness candidate باشد، نه Vulnerability exploitپذیر قطعی؛ PASS نیز absence of vulnerability نیست.
| فیلد Evidence | نمونه | چرا مهم است؟ |
|---|---|---|
| Commit | C17 | Source دقیق |
| Build config/deps | BC-17/LOCK-17 | تحلیل حلشده |
| Engine/version | SAST 5.2.0 | تکرارپذیری |
| Ruleset | SAST-R9 | Coverage/threshold |
| Scope/exclusions | src/**، generated excluded | محدودیت |
| Outcome | FINDING/ERROR/INCONCLUSIVE | تفکیک اجرا از امنیت |
| Fingerprint | fp-sast-22 | Dedup/closure |
جزئیات تحلیل ایستا و Quality Gate در راهنمای تحلیل استاتیک کد آمده است. این مقاله فقط Contract اتصال SAST به Pipeline و Policy را نگه میدارد.
SCA و SBOM: inventory، signal و exposure را جدا کنید
SCA میتواند component/version/license/advisory signal را از manifest، lockfile، SBOM یا Artifact استنباط کند. Match شدن CVE به component لزوماً به معنی reachable/exploitable بودن در Context نیست؛ نبود match نیز component ناشناخته، DB قدیمی، package alias یا vulnerability منتشرنشده را رد نمیکند. SBOM inventory است، نه scan result یا proof of safety.
| رکورد | Subject | زمان | Claim محدود |
|---|---|---|---|
| Lockfile | Source C17 | commit | declared resolution intent |
| SBOM | Artifact ART17 | build | reported component inventory |
| SCA result | SBOM17/ART17 | DB cutoff | known advisory matches |
| Reachability | code/runtime context | analysis window | evidence about reachable path |
| VEX/Disposition | specific product/version | issued/reviewed | status assertion with authority |
برای format، completeness، identity و مصرف SBOM به راهنمای مستقل SBOM مراجعه کنید.
DAST روی Application در حال اجراست؛ Build و Environment حیاتیاند
DAST ورودی را از interface قابلدسترسی به Application اجراشده میفرستد. Coverage به crawl/authentication/seed data/role/state/rate limit/network topology و safety mode وابسته است. اگر DAST روی ART15 در ENV5 اجرا و ART17 منتشر شود، سبزبودن آن Evidence انتشار ART17 نیست.
dynamicEvidence: artifactDigest: sha256:ART17 deploymentManifest: DEP-SEC-17 environment: ENV-SEC-7 baseUrlAlias: local-checkout.invalid roles: [anonymous, customer-syn, support-syn] seedData: DATA-SEC-17 scannerVersion: 2.15.0 ruleset: DAST-R5 crawlProfile: CRAWL-4 safetyMode: non-destructive-offline start/end: ISO-8601 instants coverageLimits: callback/admin paths excluded reportDigest: sha256:EV-DAST-R17
Secret scanning: Finding را با Secret handling اشتباه نکنید
اسکن Secret ممکن است با regex، entropy، provider pattern یا validation کار کند. Report نباید خود credential را در log عمومی بازنشر کند. اگر Secret واقعی وارد Repository شده، حذف Commit یا سبزشدن Job کافی نیست؛ احتمال افشا، history/cache/fork/log/artifact، revoke/rotate، blast radius، evidence retention و incident interface باید بررسی شود.
| حالت | اقدام | Evidence امن |
|---|---|---|
| Candidate false positive | Review + fingerprinted suppression | redacted type/location |
| Valid inactive test token | Policy disposition/expiry | synthetic marker |
| Valid credential | revoke/rotate/contain/investigate | secret ID hash، نه value |
| Scanner error | ERROR/UNKNOWN، نه PASS | execution error record |
| History unscanned | scope limitation | commit range |
IaC و Container: Revision و Digest را ثابت کنید
IaC scanner فایل/plan/module و policyهای پیکربندی را میبیند؛ state واقعی و تغییر خارج از IaC ممکن است متفاوت باشد. Container scan باید Image digest نهایی را ببیند، نه tag mutable یا Base image قبل از افزودن packageها. برای هر دو، platform/version، module resolution، policy bundle، exception و DB cutoff لازم است.
| کنترل | Subject درست | Mismatch خطرناک |
|---|---|---|
| IaC static | infra/main-C17.tf + modules lock | scan فایل قدیمی |
| Plan policy | plan digest برای workspace | apply plan دیگر |
| Image packages | sha256:ART17 | `registry/app:latest` |
| Base provenance | base digest | tag بدون pin |
| Runtime config | deployed manifest digest | template قبل از overlay |
خود Pipeline بخشی از Attack Surface است
CI/CD معمولاً Source، Secret، Artifact registry و محیطهای استقرار را لمس میکند و Jobهایش کد تغییرکرده را اجرا میکنند. افزودن Scanner بدون محافظت از SCM، Pipeline definition، Runner، plugin/action، cache، artifact store و identity میتواند سطح حمله را بیشتر کند. Pipeline را مانند سامانهٔ Production حساس Threat-model کنید.
| سطح | Risk | کنترل | Evidence |
|---|---|---|---|
| SCM | تغییر unauthorized | review/protected ref/signed change | change/approval log |
| Pipeline config | poisoned execution | review/policy/isolation | definition digest |
| Runner | cross-job persistence | ephemeral/isolation/hardening | runner attestation |
| Identity | credential abuse | short-lived/least privilege | principal/scope/expiry |
| Dependency/action | third-party compromise | pin/allowlist/review/update | resolved digest |
| Cache/artifact | poison/substitution | namespace/integrity/signature | digest/verification |
| Log | secret/data leakage | redaction/access/retention | policy test |
Runner Contract: چه چیزی کد نامطمئن را اجرا میکند؟
runnerContract: runnerId: runner-R17 imageDigest: sha256:RUNNER17 trustZone: untrusted-build-isolated ephemeral: true reuse: none networkEgress: allowlist-v3 filesystem: disposable identity: short-lived-workload-R17 permissions: source-read, artifact-write-R17 secrets: none for untrusted PR cacheNamespace: repo-commit-control logRedactionPolicy: LOG-RED-v2 attestation: sha256:RUN-ATT-17
این Contract تضمین نمیکند Runner compromise نشده است؛ فقط assumptions و controls را قابلبازبینی میکند. «Hosted runner امن است» یا «self-hosted بهتر است» حکم عمومی نیست. Threat، isolation، operations، tenancy، data locality، patching و evidence تعیینکنندهاند.
Artifact، Signature، Attestation و Provenance یک چیز نیستند
| مفهوم | پرسش | Claim محدود |
|---|---|---|
| Digest | بایتها هماناند؟ | content identity/integrity check |
| Signature | کدام identity این statement را امضا کرده؟ | authenticity under trust policy |
| Attestation | چه statement ساختاری دربارهٔ Subject وجود دارد؟ | claim by attestor |
| Provenance | Artifact کجا/چگونه/از چه Source ساخته شد؟ | traceable build information |
| SBOM | چه componentهایی گزارش شدهاند؟ | inventory assertion |
| Scan evidence | کدام Control روی چه Subject اجرا شد؟ | bounded test/analysis result |
امضای Artifact آسیبپذیر فقط اصالت همان Artifact آسیبپذیر را نشان میدهد. Provenance معتبر نیز امنیت Source، Builder یا محصول را بهتنهایی ثابت نمیکند؛ Trust policy باید identity، builder، source، parameters، dependencies و verification را ارزیابی کند.
Build once، promote by digest
اگر پس از Security evidence دوباره Build کنید، Subject تغییر کرده است. الگوی قابلردیابی این است که Artifact نهایی یکبار تولید، با digest شناسایی، روی همان digest کنترلها اجرا و همان digest میان Environmentها Promote شود. اگر rebuild اجتنابناپذیر است، lineage و کنترلهای Artifact تازه باید دوباره برقرار شوند.
promotionRecord:
sourceArtifact: registry/candidate@sha256:ART17
targetArtifact: registry/release@sha256:ART17
requiredEvidence:
- EV-SECRET-R17
- EV-SAST-R17
- EV-SCA-R17
- sha256:SBOM17
- EV-IAC-R17
- EV-IMG-R17
- EV-DAST-R17
- sha256:PROV17
signatureVerified: true
provenanceVerified: true
policyDecision: DEC-SEC-R17
actor: release-authority-a
instant: 2026-08-12T13:30:00Z
Job status، Control outcome و Policy decision را جدا کنید
| لایه | واژگان | مثال |
|---|---|---|
| Job | SUCCESS/FAILED/CANCELLED/TIMED_OUT | Process exit |
| Control | PASS/FINDING/ERROR/INCONCLUSIVE/NA | Result با scope |
| Finding | OPEN/DUPLICATE/FIXED/SUPPRESSED/RISK_ACCEPTED | Lifecycle |
| Evidence | AVAILABLE/MISSING/STALE/FOREIGN/INVALID | Trust/readiness |
| Policy | ALLOW/HOLD/REVIEW/EXCEPTION | Evaluation |
| Release | APPROVE/REJECT/DEFER | Authorized decision |
Job میتواند SUCCESS باشد چون Scanner بدون Report به پایان رسیده است؛ در این حالت Control باید ERROR یا Evidence=MISSING باشد، نه PASS. همچنین Scanner finding داشتن لزوماً Release=REJECT نیست؛ Risk/context، compensating control و Authority در Policy/Decision layer بررسی میشوند.
Finding را Normalize کنید، اما جزئیات را نابود نکنید
securityFinding: id: F1 fingerprint: fp-1 control: CTRL-SCA-04 subject: sha256:ART17 weakness/advisory: source-native-id observedAt: 2026-08-12T06:20:00Z severitySource: scanner exploitability: UNKNOWN reachability: NOT_ESTABLISHED businessContext: checkout-syn evidence: EV-SCA-R17#finding-1 status: OPEN owner: service-owner-a due/review: policy-derived limitation: known-data match only
Severity vendorها قابلجمع یا مقایسهٔ مستقیم نیست. یک Normalization layer باید Source score/vector، confidence، asset exposure، reachability، compensating control و uncertainty را حفظ کند. تبدیل همهچیز به High/Medium/Low بدون Source، اطلاعات تصمیم را کم میکند.
Policy-as-code باید Version و Test داشته باشد
Policy-as-code تصمیم را تکرارپذیرتر میکند، اما خود Policy ممکن است ناقص، stale یا قابلدورزدن باشد. ورودی schema، outcome vocabulary، required controls، threshold، unknown handling، fail mode، exception authority و effective window را نسخهدار کنید. با Fixtureهای positive/negative/boundary/missing/foreign/stale آن را آزمایش کنید.
policyDecisionInput: policy: SEC-POL-v4 subject: sha256:ART17 requiredControls: [secret, sast, sca, sbom, iac, image, dast] evidenceState: all required AVAILABLE + CURRENT + SAME_SUBJECT findings: normalized with uncertainty exceptions: active, approved, scoped, unexpired only unknownRule: HOLD if required evidence unknown toolErrorRule: HOLD unless explicit bounded fallback output: ALLOW | HOLD | REVIEW | EXCEPTION releaseAuthority: separate
Fail-open و Fail-closed یک دوگانهٔ ساده نیست
| وضعیت | Default ممکن | نیاز تصمیم |
|---|---|---|
| Required evidence missing | HOLD | آیا fallback معتبر وجود دارد؟ |
| Scanner unavailable | HOLD/REVIEW | Risk/window/manual control |
| Low-risk docs-only change | NA طبق applicability | classification درست؟ |
| Emergency remediation | bounded exception | authority/expiry/post-check |
| Runtime incident fix | fast path با controls حداقلی | containment و retrospective verification |
Fail-open پنهان—مثلاً تبدیل timeout به zero findings—خطرناک است. Fail-closed بیتفکیک نیز میتواند تیم را به bypass دائمی سوق دهد. انتخاب باید Risk-based، ثبتشده، زماندار و دارای telemetry باشد؛ نه رفتار ضمنی یک script.
Exception و Suppression بدهی زماندارند
| فیلد | هدف |
|---|---|
| Finding/control/subject | Scope دقیق |
| Rationale | چرا Policy عادی اعمال نشد؟ |
| Evidence/uncertainty | مبنای محدود |
| Compensating control | کاهش Risk فعلی |
| Owner/approver | پاسخگویی و authority |
| Issued/expires | جلوگیری از سکوت دائمی |
| Retest/trigger | بازگشت به Policy |
| Scope change rule | بیاعتباری روی Artifact/Context تازه |
exception: id: EX-F1-17 finding: F1 subject: sha256:ART17 status: RISK_ACCEPTED_UNTIL rationale: path not reachable in declared ENV7 model uncertainty: reachability evidence limited compensatingControl: deny-route-R17 owner: appsec-owner-a approver: risk-owner-a issuedAt: 2026-08-12T10:00:00Z expiresAt: 2026-08-27T10:00:00Z invalidatedBy: artifact/threat/environment/policy change retest: RETEST-F1-17
Compliance evidence، Compliance proof نیست
Reportهای خودکار میتوانند نشان دهند Control مشخص در زمان و Scope معین اجرا شده است. این برای Audit مفید است، اما تعیین applicability قانون/استاندارد، طراحی Control، operating effectiveness، sampling، exception، retention و نظر Auditor/Authority جداست. این مقاله هیچ ادعای انطباق با PCI DSS، GDPR، HIPAA، ISO یا قوانین ایران ارائه نمیکند.
| Claim | Evidence ممکن | فاصلهٔ باقیمانده |
|---|---|---|
| Control اجرا شد | signed execution manifest | Control مناسب/موثر بود؟ |
| Artifact اسکن شد | same-digest result | Coverage و limitation چیست؟ |
| Exception مجاز بود | authority/expiry | Risk decision درست بود؟ |
| Record نگهداری شد | retention log | Requirement درست و کامل است؟ |
| Policy passed | versioned decision | Compliance/Release approval نیست |
Shift-left کافی نیست؛ Shift-right و Feedback لازم است
کنترل زودهنگام هزینهٔ Feedback را ممکن است کم کند، اما Runtime configuration، identity، traffic، dependency disclosure و exploit تازه بعداً ظاهر میشوند. Detection، vulnerability intake، monitoring، incident response، patch/rebuild/revoke، advisory، customer communication و Retest باید به Requirement/Threat/Control برگردند. «چپ» و «راست» روی timeline استعارهاند؛ هدف، Feedback مناسب در Context مناسب است.
| زمان | Control نمونه | بازخورد به |
|---|---|---|
| Design | threat/abuse/design review | requirement/architecture |
| Source | secret/SAST/review | change author/team |
| Build | SCA/SBOM/image/provenance | dependency/build policy |
| Test | DAST/authz/manual | implementation/design |
| Promotion | signature/provenance/policy | release authority |
| Runtime | detection/monitor/intake | response/remediation/threat model |
مرز DevSecOps با Continuous Testing و Release
برای orchestration عمومی تستهای CI/CD، flaky outcome و feedback budget، طراحی Continuous Testing را ببینید. برای Security Claim، Evidence، Risk acceptance و Release authority، پروتکل همکاری QA و AppSec مالک جزئیات تصمیم است. Security Control Contract این مقاله ورودی قابلاعتماد آن تصمیمها را میسازد.
آزمایش تکرارپذیر: آیا هفت Job سبز کافی است؟
Fixture کاملاً ساختگی SYN-DEVSECOPS-CONTROL-CONTRACT-01 هفت Job موفق و صفر High finding دارد؛ کنترل سطحی `PASS` میدهد. Validator مستقل Repository/Commit/Pipeline/Policy/Threat/Build/Artifact، Runner، هر Control، Evidence، suppression، Gate، Promotion، Log و Post-deploy response را بررسی میکند.
Fixture معیوب در برابر Contract
| بعد | Contract | Draft سبز |
|---|---|---|
| Source | repo/C17/PIPE-v4 | repo قدیمی/C16/PIPE-v2 |
| Policy/Threat | SEC-POL-v4/TM-v3 | v2/v1 |
| Artifact | ART17/SBOM17/PROV17 | ART16/خالی/خالی |
| Runner | ephemeral/isolated/least privilege/pinned | shared/admin/latest |
| Controls | same subject/current rules/DB/evidence | foreign/stale/missing |
| Suppression | owner/expiry/control/approval | فقط «noise» |
| Gate | Policy input/closed unknown | self-authorized/fail-open |
| Promotion | digest/signature/provenance | `latest` بدون verify |
| Operations | redaction/retention/access/response | open/forever/all/none |
خروجی مستقل Validator: ۴۲ Finding
fixture: SYN-DEVSECOPS-CONTROL-CONTRACT-01 runtime: Node.js v26.7.0 superficial: PASS | successfulJobs=7/7 | highFindings=0 auditedDraft: HOLD findings (42): 1 wrong-repository 2 wrong-commit:C16->C17 3 stale-pipeline-definition:PIPE-v2->PIPE-v4 4 stale-security-policy:SEC-POL-v2->SEC-POL-v4 5 stale-threat-model:TM-v1->TM-v3 6 wrong-build-run:BUILD-R16->BUILD-R17 7 wrong-artifact-digest:ART16->ART17 8 missing-or-wrong-sbom-digest 9 missing-or-wrong-provenance 10 wrong-security-environment 11 missing-vulnerability-db-cutoff 12 untrusted-pr-not-reviewed 13 runner-not-ephemeral 14 runner-not-isolated 15 runner-excessive-permission 16 runner-image-not-pinned 17 secret-scan-wrong-subject 18 secret-scanner-version-unpinned 19 secret-scan-ruleset-missing 20 secret-evidence-unsafe-console-log 21 sast-wrong-subject 22 sast-version-unpinned 23 sast-evidence-missing 24 sca-foreign-artifact 25 sca-policy-missing 26 sca-db-cutoff-missing 27 sbom-not-bound-to-artifact-and-digest 28 iac-wrong-revision 29 image-scan-tag-instead-of-digest 30 image-db-cutoff-stale 31 dast-foreign-artifact 32 dast-wrong-environment 33 suppression-missing-governance 34 pipeline-self-authorized-release 35 gate-fails-open-with-unknown-evidence 36 promotion-signature-not-verified 37 promotion-provenance-not-verified 38 promotion-target-not-immutable 39 security-log-redaction-missing 40 security-log-retention-unbounded 41 security-evidence-access-too-broad 42 post-deploy-detection-response-missing corrected: READY_FOR_POLICY_DECISION | findings=0
نسخهٔ اصلاحی چه چیزی را ثابت کرد؟
نسخهٔ اصلاحی repo/C17/PIPE-v4/SEC-POL-v4/TM-v3/BUILD-R17 و ART17/SBOM17/PROV17/ENV7/DB cutoff را قفل کرد؛ Trigger مورداعتماد و Runner ephemeral/isolated/least-privilege/pinned ساخت؛ Secret/SAST/SCA/SBOM/IaC/Image/DAST را به Subject/نسخه/Ruleset/Evidence درست بست؛ Exception را Owner/Expiry/Control/Approval داد؛ و Promotion همان digest را با Signature/Provenance verify کرد.
`READY_FOR_POLICY_DECISION` فقط آمادگی ساختاری ورودی Policy را میگوید. صحت Tool/DB/Report، کفایت Threat/Control/Coverage، نبود Vulnerability، امنبودن Runner/Artifact، اعتبار Risk acceptance، Compliance و Release را اثبات نمیکند. Decision owner باید Evidence و Unknown را با Context واقعی بازبینی کند.
آزمایشگاه DevSecOps فارسی، ساختگی و آفلاین
دامنهٔ تمرینی یک Checkout خیالی و جدا از شبکه است: Repository/Commit، Order، PaymentAttempt، PSP Stub، Callback، Ledger، Reconciliation، Container image و local registry. هیچ Source عمومی، Registry بیرونی، Production، شرکت، کاربر، پرداخت، بانک یا PSP واقعی در آزمایش حضور ندارد. Advisory database نیز Fixture محلی با cutoff ساختگی است.
| بعد | قاعدهٔ Lab |
|---|---|
| Artifact | digestهای ساختگی و immutable local registry |
| SBOM/Provenance | Fixture امضاشده با کلید آزمایش یکبارمصرف |
| Threats | duplicate/late/reordered callback، dependency/pipeline substitution |
| Money | IRR خیالی Canonical؛ تومان فقط View صریح |
| Digits/RTL | فارسی/عربی/لاتین و bidi controls |
| Time | UTC instant + Asia/Tehran؛ جلالی فقط Presentation |
| Secrets | markerهای synthetic؛ بدون PAN/CVV2/OTP/token/credential |
| Network | deny-all؛ Source/tool/DB/image محلی |
| Claim | بدون ادعای امنیت/بانک/قانون/Compliance ایران |
نمونهٔ Matrix کنترل در Lab
| Risk | Subject | Control | Evidence | Unknown |
|---|---|---|---|---|
| synthetic secret marker | C17 | Secret rule SECRET-R4 | redacted EV-SECRET | obfuscated patterns |
| unsafe callback parsing | C17 | SAST + code review | EV-SAST/REV | runtime path |
| fixture advisory | ART17/SBOM17 | SCA local DB | EV-SCA | reachability |
| open local port | IaC C17 | IaC policy | EV-IAC | runtime overlay |
| role bypass | ART17/ENV7 | authz regression + DAST | EV-AUTHZ/DAST | unmodeled role |
| artifact swap | ART17 | digest/signature/provenance | PROV17/PROMO | builder trust |
تیم کوچک از کجا شروع کند؟
- یک Service و یک Artifact path را انتخاب کنید.
- Threat/Asset/Requirementهای محدود را ثبت کنید.
- Source/Commit/Build/Artifact/Environment identity را برقرار کنید.
- خود SCM/Pipeline/Runner/Secret/Artifact store را سختسازی کنید.
- یک کنترل سریع Source و یک کنترل Artifact اضافه کنید.
- Outcome و ERROR/UNKNOWN را تفکیک کنید.
- Finding/Triage/Exception/Retest interface بسازید.
- Policy را روی Fixtureهای missing/stale/foreign آزمایش کنید.
- Promotion by digest و Provenance verification را اضافه کنید.
- Runtime response و vulnerability intake را ببندید.
ابزار رایگان یا متنباز میتواند مناسب باشد، اما «رایگان» بودن Coverage، maintenance، update channel، license، support، data handling و exit cost را حل نمیکند. PoC را بر قابلیت و Fixture نماینده بنا کنید، نه فهرست محبوبیت یا محدودیت دسترسی یک Vendor.
Tool PoC را با قابلیت و Failure mode بسنجید
| قابلیت | Fixture | Signal | Failure/Exit |
|---|---|---|---|
| Subject binding | ART17/ART16 pair | foreign rejected | cannot bind digest |
| Ruleset/version | known delta | manifest reproducible | silent auto-update |
| Error semantics | DB unavailable | ERROR not PASS | zero findings |
| Evidence export | normalized + raw | stable IDs/digests | vendor-only view |
| False-positive flow | known candidate | expiry/retest | global ignore |
| Privacy | synthetic secret/log | redaction/access | uncontrolled upload |
| Performance | representative repo | distribution/queue | fixed universal SLA |
| Exit | export/migration | portable evidence/policy | lock-in unacceptable |
Remote، SaaS و محدودیت دسترسی در ایران
Data residency، تحریم/دسترسی، account continuity، update mirror، artifact upload، source confidentiality و incident support را بهعنوان Constraint عملی ثبت کنید؛ نه اینکه کنترل را مخفیانه خاموش یا ادعای حقوقی بسازید. برای هر SaaS یک local fallback یا documented degraded mode، expiry و Owner تعریف کنید. Mirror و package source نیز باید integrity/provenance و update policy داشته باشند.
امنیت Evidence و Log
| داده | ریسک | کنترل |
|---|---|---|
| Source snippet | IP/secret disclosure | minimal excerpt/reference/access |
| DAST request/response | token/PII | synthetic data/redaction/encryption |
| SBOM | architecture disclosure | audience/classification |
| Finding | exploit roadmap | need-to-know/severity channel |
| Runner log | credential exfiltration | masking not sufficient; no secret exposure |
| Attestation | metadata leakage/forgery | schema/signature/trust/retention |
| AI prompt | external data transfer | approved model/redaction/no raw secret |
AI در DevSecOps: triage assistant، نه Risk authority
AI میتواند duplicate candidate، explanation، remediation draft، rule suggestion یا evidence-gap بسازد. مدل/نسخه، prompt/template، input classification، output digest، زمان و reviewer را ثبت کنید. AI نباید Secret یا Source مجازنشده را دریافت کند، Finding را بیبررسی close کند، exploitability را قطعی بداند، Policy را دور بزند یا Risk/Release را بپذیرد. Prompt injection از Source/Issue/Artifact نیز Threat است.
نقشها و حق تصمیم
| Capability/Role | Accountability محلی | مرز |
|---|---|---|
| Developer | secure change/remediation/evidence | Risk acceptance خودکار نیست |
| Tester/QA capability | testability/oracle/evidence/negative paths | مالک امنیت یا Release نیست |
| AppSec | control/rule/triage expertise | تنها سازندهٔ امنیت نیست |
| Platform/DevOps | pipeline/runner/identity/artifact | Policy outcome را جعل نمیکند |
| Service owner | service risk/remediation | خارج از authority استثنا نمیدهد |
| Risk owner | bounded acceptance | Evidence truth را تضمین نمیکند |
| Release authority | release decision | سبزی Pipeline جای تصمیم نیست |
| Security operations | detection/response/intake | Development feedback را قطع نمیکند |
متریکهای سلامت Pipeline و Countermetricها
| متریک | تعریف نسخهدار | Countermetric |
|---|---|---|
| Required evidence completeness | current same-subject evidence / applicable required | NA/exception growth |
| Finding age | open time by policy class | mass suppression/closure |
| Retest closure | verified fixed / eligible fixes | reopen/foreign build |
| Exception debt | active/expired by risk | renewal without evidence |
| Pipeline feedback time | distribution by control/change | skipped control/queue |
| Runner trust coverage | attested eligible runs / runs | untrusted fast path |
| Artifact lineage | release digests with verified provenance | signed vulnerable artifact |
| Tool error rate | ERROR/eligible executions | errors mapped to PASS |
تعداد Finding، صفر High، درصد اسکن یا زمان Pipeline بهتنهایی KPI امنیت یا بهرهوری فردی نیست. denominator، applicability، subject، ruleset، DB cutoff و unknown را حفظ کنید. مقایسهٔ تیمها معمولاً تفاوت Threat/Stack/Exposure را حذف و Gaming ایجاد میکند.
۳۰ ضدالگوی DevSecOps Pipeline
- DevSecOps برابر خرید ابزار
- Scanner count بهعنوان maturity
- Pipeline green برابر secure
- صفر High برابر absence of risk
- Job success برابر Control pass
- Tool error برابر zero findings
- Branch/tag mutable بهعنوان Subject
- SCA/DAST روی Artifact دیگر
- SBOM بدون digest binding
- Provenance بدون verification
- Signature برابر vulnerability-free
- Rebuild پس از scan بدون controls تازه
- Untrusted PR روی Runner پرامتیاز
- Runner مشترک پایدار بدون isolation
- Action/plugin/image با `latest`
- Secret در log/report
- DB cutoff و Ruleset نامعلوم
- Suppression جهانی «noise»
- Exception بدون expiry/owner/approval
- Severity vendor برابر business risk
- Gate بهعنوان Release authority
- Fail-open پنهان
- Fail-closed بیتفکیک و bypassساز
- Compliance با screenshot Scanner
- Shift-left بدون runtime response
- Shared responsibility بدون decision rights
- Coverage بدون Threat/Requirement
- AI closure یا risk acceptance
- Evidence retention بیانتها
- فهرست Vendor به جای Control Contract
Pilot سیروزهٔ Security Control Contract
| بازه | کار | Exit محدود |
|---|---|---|
| روز ۱–۳ | Service/Threat/Requirement/authority | Scope و Risk register |
| روز ۴–۷ | Source→Build→Artifact→Environment identity | same-subject lineage |
| روز ۸–۱۲ | Runner/IAM/Secret/artifact hardening | Trust assumptions ثبت |
| روز ۱۳–۱۸ | دو تا چهار Control مکمل | Evidence/outcome semantics |
| روز ۱۹–۲۲ | Finding/Exception/Retest | Closure interface |
| روز ۲۳–۲۶ | Policy Fixtureهای stale/foreign/missing | fail mode روشن |
| روز ۲۷–۲۸ | Promotion digest/provenance | verified lineage |
| روز ۲۹–۳۰ | Tabletop runtime disclosure/response | Feedback loop و next gaps |
Pilot موفق یعنی Control و Evidence روی Subject درست اجرا، Policy با Failure mode آزموده، Exception زماندار و Promotion قابلردیابی شده است. کاهش Vulnerability، هزینه یا زمان باید در Window و Population مستقل سنجیده شود و از یک Pilot کوچک به کل سازمان تعمیم داده نشود.
چکلیست Audit قبل از Policy decision
- Product/Repository/Commit/Pipeline/Policy/Threat model/Build/Artifact/Environment/Cutoff ثابتاند.
- Artifact، SBOM، Provenance و Evidence با digest به هم متصلاند.
- Controlها به Risk/Requirement و applicability وصلاند.
- Tool/version/ruleset/config/data cutoff/scope/limitation ثبت است.
- Job status از Control outcome و Evidence state جداست.
- ERROR/UNKNOWN/INCONCLUSIVE هرگز به PASS نگاشته نشده است.
- Untrusted input روی Runner مناسب، ephemeral و least-privilege اجرا میشود.
- Plugin/action/image/dependency pin و update policy دارد.
- Secret در Source/Log/Evidence/AI prompt بازنشر نشده است.
- SAST/SCA/SBOM/IaC/Image/DAST Subject درست و جاری دارند.
- Finding fingerprint، Evidence، uncertainty، owner و lifecycle دارد.
- Suppression/Exception scoped، approved، compensating، expiring و retestable است.
- Policy schema/version/tests/unknown rule/fail mode روشن است.
- Policy decision از Risk acceptance و Release authority جداست.
- Promotion همان Artifact digest را با Signature/Provenance verify میکند.
- Evidence access/redaction/retention/deletion/classification مشخص است.
- Runtime detection، vulnerability intake، response، remediation و Retest متصلاند.
- Compliance/secure/cost/speed claims از Evidence فراتر نرفتهاند.
نقشهٔ مطالعهٔ مرتبط
برای مبانی تست امنیت از راهنمای تست امنیت نرمافزار، برای Shift-left عمومی از نقشهٔ کیفیت از Discovery تا CI، برای Portfolio ابزار از مقالهٔ SAST/DAST/SCA، برای SBOM از راهنمای اختصاصی آن، برای Continuous Testing از مقالهٔ خط لوله و برای Risk/Release از همکاری QA–AppSec استفاده کنید. Security Control Contract این صفحه ستون اتصال آنهاست.
پرسشهای متداول
آیا DevSecOps فقط همان Shift-left Security است؟
خیر. بازخورد زودهنگام مهم است، اما DevSecOps باید طراحی، Source، Build، Artifact، Pipeline، Promotion و Runtime response را پوشش دهد. بعضی کنترلها در Design یا Commit ارزانترند؛ بعضی فقط روی Application اجراشده، Artifact نهایی یا محیط عملی معنا دارند. هدف right-control/right-subject/right-time است.
اگر همهٔ Scannerها سبز باشند، میتوان Release کرد؟
نه بهصورت خودکار. ابتدا Subject/نسخه/Ruleset/DB cutoff/Evidence/Error/Unknown/Exception و Coverage را بررسی کنید و مطمئن شوید همان Artifact Promote میشود. Policy نتیجه یک ورودی است؛ Risk acceptance و Release decision به Authority و Context سازمان وابستهاند. سبزی Scanner نبود Vulnerability یا امنیت محصول را ثابت نمیکند.
تفاوت SBOM، SCA و Provenance چیست؟
SBOM ادعای inventory componentهای یک Subject است؛ SCA آن inventory/Artifact را با داده و policy تحلیل میکند و advisory/license signal میسازد؛ Provenance اطلاعات قابلبررسی دربارهٔ محل، زمان و روش تولید Artifact را حمل میکند. هیچکدام بهتنهایی امنیت، absence of vulnerability یا Compliance را اثبات نمیکنند.
با False Positive و Exception چه کنیم؟
Finding را با Evidence و fingerprint بازبینی کنید. اگر suppression یا Risk acceptance لازم است، Subject/Scope، rationale، uncertainty، compensating control، owner، approver، issued/expiry و retest را ثبت کنید. Global ignore و «noise» بدون انقضا، Control را خاموش میکند. تغییر Artifact/Threat/Environment/Policy باید Exception را بیاعتبار کند.
یک تیم کوچک ایرانی بدون SaaS خارجی چگونه شروع کند؟
با یک Service و Lab آفلاین، Threat محدود، Artifact digest، Runner کماختیار و دو Control مکمل شروع کند. Tool/Rule/DB را pin و mirror را verify کند، Evidence export و fallback را آزمایش و هیچ Secret/PII واقعی وارد Fixture نکند. محدودیت دسترسی یا داده را ثبت کند؛ این راهنما توصیهٔ حقوقی، تحریمی یا Compliance ایران نیست.
جمعبندی: از Scanner سبز به Control قابلاعتماد
DevSecOps زمانی قابلبازبینی میشود که Threat و Requirement به Control برسند؛ Control به Commit/Artifact/Environment درست بسته شود؛ Runner و Pipeline خودشان محافظت شوند؛ Result با Tool/Rule/DB/limitation به Evidence تبدیل شود؛ Policy، Unknown و Exception را صریح اداره کند؛ و همان Artifact با Signature/Provenance به Runtime برسد و مسیر Response/Retest باز بماند. ابزار و Automation سرعت Feedback میدهند، اما «امن»، «مطابق»، «کمهزینه» یا «قابل انتشار» را بهتنهایی ثابت نمیکنند.

