diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..79b5594 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +**/.DS_Store diff --git a/devsecops/LICENSE b/devsecops/LICENSE new file mode 100644 index 0000000..03c9b42 --- /dev/null +++ b/devsecops/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2024 aamkye + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/devsecops/readme.md b/devsecops/readme.md new file mode 100644 index 0000000..bf1dcfa --- /dev/null +++ b/devsecops/readme.md @@ -0,0 +1,282 @@ +# DevSecOps + +## What is DevSecOps? + + + +In the realm of modern craft, there arose a practice known among the learned as DevSecOps, a union of three great disciplines: development, security, and operations. It was not unlike the forging of a mighty alliance, wherein each realm must contribute its strength, lest their endeavors fall prey to the shadows of vulnerability. + +In days past, many would wait until the final hour, when the code was near release, before calling upon the wardens of security. Yet this path was fraught with peril, for to uncover weaknesses so late would often cost dear in time, gold, and effort. But the wisest of realms soon saw another way. + +By weaving security into every phase of the craft—whether in the laying of the first line of code or the final shaping of the product—teams could safeguard their work from the outset. Through deep collaboration and the magic of automation, they crafted a system where all shared the burden of protection. Thus, no longer was security the task of the few, but of all who toiled together, forging a shield that would hold fast even in the face of the darkest threats. + +In this way, DevSecOps was not merely a method, but a way of ensuring that no creation would leave the forges unguarded against the unseen dangers lurking in the shadows. + +## DevOps vs DevSecOps + + + + +In the lands of traditional software craft, the crafting of great projects was long governed by the old ways, where the work was divided into phases—like the seasons of the year—each flowing one after the other. There would come a time for planning, then design, and only after would the labor of development begin, followed by the testing and binding of all parts into a whole. Yet, this process, while orderly, was as slow as the march of the seasons themselves. In an age where the winds of change blow swift and customers' desires are ever-shifting, such a pace no longer sufficed. + +Worse still, the guardians of security were oft called upon at the very end, when the work was near complete, to cast their protections over the product. Alas, this lateness was fraught with danger, for vulnerabilities uncovered at such a time could unravel much of the work that had come before. + +Thus, many of the great guilds of craft turned to a new way: the DevOps model. Here, rather than waiting for the long seasons to pass, the teams delivered smaller, yet finely crafted parcels of work—each one polished and ready—rather than undertaking vast projects that stretched on for years. In this way, the teams of development and operations joined forces, testing and refining their work as they went. By using the tools of automation and forging standardized processes, they moved with great speed, yet kept the quality of their craft intact. + +But in time, the guilds realized there was a further step to be taken. They sought not just swiftness, but security woven into every step of their journey. And so was born DevSecOps, where security was not an afterthought but a companion to every stage of the craft. From the very first whispers of planning, security was present, and in the fires of development, it was tested and shaped alongside the code. The burden of protection no longer lay on the shoulders of a few, but on the entire fellowship of creators. This new way became known to some as ‘shift left security,' for it brought the guardians of protection to the forefront of the process, ensuring that no ill would befall their work from the very start of the journey to its end. + +## Importance of DevSecOps + + + +In the ever-shifting shadows beyond the borders of an organization's walls, there lurk many foes, seeking to gain entry and plunder its most valuable treasures—its data and assets. Among the many dark arts these foes employ, one of the most common is the exploitation of weaknesses, hidden deep within the folds of the organization's own software. These vulnerabilities, if left unchecked, are like cracks in the foundation of a mighty fortress, and through them, adversaries can slip in unnoticed, wreaking havoc from within. + +Such breaches can be devastating. They consume both time and treasure to mend, and in their wake, they leave scars upon a company's name, causing trust to wither among clients and allies alike. + +But there is hope within the craft of DevSecOps. By following this path, the guilds of development, security, and operations stand together, ever watchful. The framework is like a vigilant sentry, reducing the risk of sending forth software riddled with flaws, misconfigurations, or vulnerabilities. Through constant vigilance and the weaving of security into every phase of creation, they close the gates through which bad actors might pass, fortifying their code so that it may stand strong against the onslaught of those who would seek to exploit it. Thus, the company stands firm, its reputation unshaken, its defenses prepared for the battles yet to come. + +### Continuous integration + + + +In the world of software craft, there once was a time when the labor of many artisans was brought together only at the final hour, when all the pieces were near completion. But it was often in those moments, at the very end, that flaws were revealed, and the seams of their work would unravel, leaving them with a tangle of issues too great to swiftly resolve. + +But a new method arose, known as Continuous Integration, a practice where the builders of code did not wait for the end to unite their works. Instead, they would commit their efforts to a central repository many times throughout the day, like artisans returning to the hearth to meld their creations together piece by piece. Each time they did so, their work was automatically tested and integrated, ensuring that all parts fit together in harmony. + +By catching integration issues and bugs early, long before the final forge was set aflame, this approach saved the guilds from the chaos of last-minute discoveries. Instead of waiting for a single moment, fraught with uncertainty, they ensured their work remained steady and true, addressing problems as they arose. Thus, they crafted their creations with foresight, and the path to completion became smoother and less perilous. + +### Continuous delivery + + + +Building upon the foundation of Continuous Integration, a further craft emerged, known as Continuous Delivery. Where the former ensured that code was swiftly integrated and tested, Continuous Delivery took this one step further, automating the journey from the builder's hands to a staging environment, where the true mettle of the code would be tested. + +Once the code reached this staging ground, it did not rest. The system immediately set to work, not only with unit testing, but with a series of trials to ensure that all aspects of the creation were sound. The user interface was inspected to ensure it responded as intended, the seams of integration were examined for any weaknesses, and the APIs were tested to confirm they communicated faithfully between systems. The code was also tested under the weight of simulated traffic, to see if it could bear the burden of the many users it would one day serve. + +Through this meticulous process, the guilds ensured that what emerged from staging was no half-finished creation, but code ready for the rigors of the real world. The aim of Continuous Delivery was simple but profound: to consistently deliver code that was not only complete, but of true value to those who would use it, ensuring that at any moment, the work could be sent to production, bringing swift and reliable benefits to all who depended on it. + +### Continuous security + + + +In the crafting halls of DevSecOps, one of the most vital elements is the weaving of security into every step of the software's journey, from the first stroke of design to the final unveiling. No longer could security be treated as an afterthought, called upon only when the work was nearly complete. Instead, it became a core part of the process, guiding the work like an unseen but ever-present hand. + +From the earliest stages, when the blueprints of the software were still taking shape, the guilds would engage in threat modeling, a process of foresight where they sought to uncover any potential dangers that might arise. They did not wait for the enemy to strike, but anticipated its moves, fortifying their code against unseen attacks before they could take root. + +As the work progressed, security testing was woven into every stage of the craft. Automation played a key role, testing the code continuously, from the developers' own environments to the farthest reaches of the deployment pipeline. No phase was left unguarded; no section of code went untested. + +Through this constant vigilance—testing early and testing often—the guilds were able to find and mend weaknesses swiftly. And so, they delivered their creations with confidence, knowing that each line of code was protected from the threats that lurked beyond. With DevSecOps, the road to production became one of fewer pitfalls and greater security, allowing organizations to deliver software swiftly and with minimal issues, their work as strong as the walls of a fortress built to endure the tests of time. + +### Communication and collaboration + + + +In the practice of DevSecOps, the strength of the craft does not lie solely in the tools or the processes but in the fellowship of those who undertake the journey together. It is a path that demands more than mere skill; it calls for deep collaboration and unity of purpose among individuals and teams. + +When the artisans commit their work to the central repository in the practice of Continuous Integration, conflicts in code inevitably arise. But it is through collaboration—where minds come together, and voices are heard—that these challenges are resolved. Developers, security experts, and operations alike must work side by side, swiftly addressing these conflicts so the flow of progress is not hindered. + +But beyond the technical work, there is a greater need—communication. Teams must speak openly and often, sharing their visions and aligning around the same goals. Without this shared understanding, the work would drift in many directions, and the efforts of one might undo the labors of another. In DevSecOps, every hand contributes to the same creation, and every voice is heard in the great chorus of the craft. + +Only when individuals unite, not just in action but in purpose, can DevSecOps truly thrive. It is through this harmony of minds and hands that the work moves forward swiftly, safely, and in accordance with the goals they all share, bringing forth creations that stand the test of time. + +## DevSecOps Practices (Shift security left) + +### Planning and development + + + +Introducing security early into the rhythm of development sprints is akin to fortifying the foundations of a great structure before the first stones are laid. By addressing vulnerabilities in the early stages, teams not only reduce the risk of future threats but also save valuable time, for it is far easier to mend potential flaws before the code has been built and woven into the greater tapestry of the project. + +At the start of every sprint, during planning and development, threat modeling becomes a crucial tool, a map guiding the teams to uncover and mitigate potential dangers long before they can manifest. By identifying these threats early, security is no longer something that is added at the end, but something that is woven into the very fabric of the application from the outset. + +To ensure no dangers slip through the cracks before the code is committed to the shared repository, automated checks are employed, acting as vigilant sentries. Integrated development environment (IDE) security plug-ins provide developers with immediate feedback, warning them if their code harbors a potential risk. These automated checks catch flaws early, empowering developers to address them before they can take root. + +As the code continues its journey, passing from one set of hands to the next, the craft is further refined during the code review. Here, someone with the wisdom of security steps forward, offering their insight and making recommendations to bolster the work. This expertise ensures that, by the time the code is ready to move on, it is fortified against threats, and the path forward is more secure. + +By embedding security into every stage, from the first lines of code to the final review, the team creates software that is not only functional and valuable but strong, resilient, and prepared for whatever challenges lie ahead. + +### Code commit + + + + +A cornerstone of the DevSecOps process lies in the practice of continuous integration, a discipline that ensures code is not simply created in isolation but is constantly woven into the central repository, allowing teams to catch issues before they can fester. Developers, like diligent artisans, commit their code several times a day, ensuring that each piece of work seamlessly fits into the greater whole. This frequent integration allows potential conflicts or errors to be discovered early, long before they can threaten the stability of the project. + +However, to truly safeguard the craft, it is vital to introduce security into this phase. Automated security checks must stand guard alongside the integration process. These include scanning third-party libraries and dependencies—those external pieces of code that, while useful, may harbor unseen vulnerabilities. Unit testing ensures the smallest parts of the code function as they should, while static application security testing (SAST) reviews the code for weaknesses, searching for hidden threats that might otherwise go unnoticed. + +But safeguarding the code itself is not enough. The continuous integration (CI) and continuous delivery (CD) infrastructure, which carries this code from creation to deployment, must also be protected. Role-based access controls (RBAC) play a crucial role in this defense, limiting access to the system based on the specific roles of individuals. By ensuring that only those with the right permissions can interact with the CI/CD infrastructure, teams protect it from attackers who might seek to run malicious code or steal credentials. + +In this way, the continuous integration process becomes not only a means to unite code swiftly and efficiently but also a stronghold against external threats. Security is built into every layer, from the automated checks that scan the code to the protections guarding the very systems that bring the work to life. + +### Building and testing + + + +In the realm of DevSecOps, where vigilance is paramount, the test environment serves as a proving ground for code before it ventures into production. Here, automated security scripts take up the role of sentinels, seeking out potential threats that may have slipped past earlier defenses. By running these tests in a controlled environment, teams can uncover hidden vulnerabilities and ensure their work remains strong and secure. + +Among the many tests that can be employed during this phase is Dynamic Application Security Testing (DAST), which simulates real-world attacks against the running application. Unlike static tests, DAST operates while the application is live, identifying vulnerabilities such as cross-site scripting, SQL injection, and other dangerous flaws. + +Infrastructure scanning follows, casting its gaze across the entire architecture, from servers to networks, searching for weaknesses in the foundational layers that might allow an attacker entry. For those employing containers as part of their deployment strategy, container scanning ensures that these lightweight units of software do not harbor vulnerabilities in their dependencies or configurations, fortifying them before they are deployed. + +In the age of the cloud, where infrastructure is often abstracted and spread across vast digital realms, cloud configuration validation becomes crucial. By checking the configurations of cloud resources, teams can ensure that no misconfigurations—such as excessive permissions or insecure access points—expose their environments to unnecessary risk. + +Lastly, security acceptance testing ensures that all necessary security requirements are met. This step serves as the final safeguard, confirming that the code and infrastructure are not only functional but fortified against known threats. + +By running these automated security scripts in the test environment, organizations create a final layer of defense, ensuring that the code is ready to face the challenges of the real world. With each vulnerability caught and addressed before deployment, the risks are minimized, and the path forward is made more secure. + +### Production + + + +Once the application has been deployed to production and stands in the real world, some organizations take a proactive step to uncover any remaining weaknesses by engaging in penetration testing. This practice is more than just another test—it is a deliberate attempt to breach the application as an attacker might, with real-world tactics and determination. + +In penetration testing, skilled individuals, often referred to as ethical hackers, adopt the mindset of a potential adversary. They probe the application for weaknesses, using the same strategies and tools a malicious actor might employ. These tests can range from exploiting known vulnerabilities in third-party components to crafting more sophisticated attacks aimed at bypassing the application's defenses. + +The goal is simple: to expose any weaknesses that might have slipped through the earlier layers of security testing, those that could potentially be exploited in the wild. By simulating real-world attack scenarios, penetration testing reveals how the application holds up under direct assault, whether it's vulnerable to unauthorized access, data breaches, or other forms of compromise. + +This phase is crucial for understanding not just theoretical vulnerabilities but how the system behaves in a live environment, where the stakes are highest. Penetration testing provides organizations with invaluable insights into the robustness of their defenses, allowing them to patch any remaining weaknesses before an actual attacker can exploit them. Thus, it becomes the final line of preparation, ensuring that the application is truly ready to stand firm against threats in the production environment. + +### Operation + + + +Even with the most robust DevSecOps process, no system is entirely impervious to evolving threats. This is why continuous monitoring of applications becomes essential once they are deployed. As applications interact with the real world, new vulnerabilities and unforeseen threats can emerge. By maintaining constant vigilance, organizations can quickly detect, respond to, and mitigate these risks before they cause significant harm. + +Monitoring tools scour the live environment for signs of irregularities, scanning for vulnerabilities, unauthorized access attempts, or other suspicious activities that might signal a breach or weakness. These tools provide real-time insights, alerting teams to potential issues the moment they arise, ensuring that no threat goes unnoticed for long. + +To further strengthen this defense, analytics data plays a key role. By analyzing patterns and trends in security events, teams can evaluate the effectiveness of their security posture. This data offers valuable insights into how well current defenses are performing, allowing organizations to track whether they are improving over time or if new vulnerabilities are emerging. It also highlights areas that may require optimization, guiding future efforts in reinforcing the system. + +In the world of security, the battle is never truly over. Even after an application is deployed and tested, constant monitoring and analysis ensure that defenses stay strong and evolve in step with the threats. By combining real-time monitoring with analytics, organizations can not only detect vulnerabilities but also continuously refine their security approach, ensuring that they stay one step ahead of potential attackers. + +## Implementing DevSecOps and automating security practices + +We bid you to consider these tools as you embark upon the journey of DevSecOps automation within your organization. Some are like fruit hanging low upon the bough, easily gathered and swiftly put to use, while others may lie deeper within the forest, requiring more effort to attain. Yet, though the path to them may be more difficult, the rewards they yield are well worth the quest. + +### Trivvy + +[Trivy](https://github.com/aquasecurity/trivy) has risen to prominence as a trusted sentinel among open-source security scanners, celebrated for its reliability, swiftness, and simplicity. It offers a far-reaching array of security checks, making it a vital companion for those seeking to fortify their DevSecOps practices. For teams looking to secure their realms of code and infrastructure, Trivy stands as a steadfast tool, ever vigilant and ready to ensure the safety of their creations. + +Targets (what Trivy can scan): +- Container Image +- Filesystem +- Git Repository (remote) +- Virtual Machine Image +- Kubernetes +- AWS + +Scanners (what Trivy can find there): +- OS packages and software dependencies in use (SBOM) +- Known vulnerabilities (CVEs) +- IaC issues and misconfigurations +- Sensitive information and secrets +- Software licenses + +### Trufflehog + + + +In the realm of software, where secrets lie hidden in the deep recesses of code repositories, there is a tool known as [TruffleHog](https://github.com/trufflesecurity/trufflehog), a masterful seeker of concealed passwords and keys. Like a skilled ranger, TruffleHog ventures where few dare to tread, unearthing the hidden secrets that, if left unchecked, could spell doom for the unwary. + +How TruffleHog Wields Its Power: +- Detect: TruffleHog scours the history of all platforms, much like a wise lorekeeper sifting through ancient scrolls, seeking out long-forgotten secrets. Yet it looks not only in the obvious places but also in the whispers of comments, the hidden folds of Docker images, and other obscure corners. +- Analyze: With the keen eye of a strategist, TruffleHog Analyze reveals the true nature of the secrets it uncovers, discerning what resources and permissions are tied to API keys and other precious tokens. Remarkably, it achieves this without ever needing to peer into the provider's vault. +- Prevent: To stop the ill-fated inclusion of secrets from the very beginning, TruffleHog sets traps at key points, using pre-commit and pre-receive hooks. These safeguards ensure that no sensitive data is unintentionally leaked before it ever leaves the developer's hand. +- Remediate: Ever vigilant, TruffleHog continues to track the fate of discovered keys and secrets. It verifies that remediation is complete, sending reminders on preferred platforms and providing the wisdom to guide users on how to properly rotate and secure the keys that were once at risk. + +Why TruffleHog Is a Worthy Ally: +- Comprehensive Multi-Branch Analysis: TruffleHog does not simply guard the main road but patrols every path. It scans all branches, not just the primary one, ensuring the same level of vigilance across the entire project. This is especially valuable in larger domains where many branches are being worked on in tandem. +- Credential Verification: For each secret it uncovers, TruffleHog employs programmatic verification, testing each credential using its own protocol or API. This removes the false trails, ensuring that only real threats are brought to light. +- Open-Source Fellowship: As with any great alliance, TruffleHog thrives through the support of an open-source community. Many dedicated hands join together to audit and improve the tool, ensuring that no single voice carries undue weight. The community checks and balances each other's work, so that trust is shared among all. + +### Snyk + + +- +In the wide lands of modern software craft, where both applications and cloud realms are wrought by skilled developers, there exists a powerful tool known as [Snyk](https://github.com/snyk/cli). This platform, much like a vigilant sentinel, guards the entirety of an application's journey—from the very first lines of code to its deployment in the vast expanse of the cloud. Through its guidance, developers may discover and mend vulnerabilities before they are ever loosed upon the world. + +The Powers of Snyk: +- Snyk Open Source: With the wisdom of the ancients, Snyk scours open-source libraries and dependencies, seeking out vulnerabilities hidden within their folds. And when such flaws are found, it does not merely warn the developer but offers a swift means to mend them, restoring the strength of the code. +- Snyk Code: As code is written, Snyk watches in real-time, finding and fixing vulnerabilities within the very heart of the application. It is like a companion at the developer's side, ever watchful and ready to lend its aid as the work is crafted. +- Snyk Container: In the realms of containers and Kubernetes, where applications are housed, Snyk's gaze does not falter. It delves into container images, finding and repairing vulnerabilities that could otherwise bring harm to these vital vessels. +- Snyk Infrastructure as Code: With great foresight, Snyk peers into the blueprints of infrastructure itself, examining the configurations of Terraform and Kubernetes code. Should it find any insecurity in the very foundation, it offers swift guidance on how to rectify these flaws, ensuring that the structure remains strong and secure. + +### Pre-commit + + + +In the vast lands of software development, where many languages and tools converge, there exists a framework known as [Pre-commit](https://github.com/pre-commit/pre-commit) — a powerful system for managing and maintaining pre-commit hooks across many tongues of code. Like a watchful steward, Pre-commit ensures that no errant detail is left unchecked before the code is sent forth for review. + +In the world of Git, hook scripts act as sentinels at the gate, catching simple errors before they reach the eyes of a reviewer. Whenever a developer commits their work, these hooks spring into action, pointing out issues such as missing semicolons, trailing whitespace, or forgotten debug statements. By addressing these small matters early, Pre-commit allows the reviewer to focus on the grand architecture of the changes, rather than wasting time on trivial style errors. + +Yet as our libraries and projects grew in number, we found the task of sharing our pre-commit hooks between them to be burdensome. We were forced to copy and paste cumbersome bash scripts from one project to another, manually adjusting them for each new structure. The effort was like carrying a heavy burden across the lands, with each step weighed down by inefficiency. + +We believe that the best tools should always be at your service, even if they hail from distant lands. Some of the finest linters are written in languages that may not even touch your own project. Take scss-lint, a linter for SCSS written in the language of Ruby—if you were crafting your project in Node, why should you be forced to burden your work with Ruby's Gemfile or wrestle with its arcane installation? + +Pre-commit frees you from such toil. It is a package manager for pre-commit hooks across many languages, both familiar and foreign. You need only specify the hooks you desire, and Pre-commit will manage the installation and execution of any hook, no matter the language it was written in. It requires no root access, and if one of your comrades lacks the proper tools—such as Node for JavaScript—Pre-commit will summon the necessary tools, downloading and building them without the need for elevated privileges. + +### Wazuh + + + +In the ever-shifting landscapes of the digital realms, where threats lurk unseen and dangers arise without warning, there is a powerful ally known as [Wazuh](https://github.com/wazuh/wazuh). Free and open to all, Wazuh stands as a vigilant guardian, skilled in the arts of threat prevention, detection, and response. It is a protector capable of defending the realms of on-premises fortresses, virtualized strongholds, containerized ships, and vast cloud kingdoms alike. + +The strength of Wazuh lies in two parts: its endpoint security agents, which are deployed like watchful sentinels to the systems they protect, and its management server, a wise and ever-alert overseer. The agents gather knowledge and data from the systems they monitor, and the management server collects, analyzes, and interprets this information, ever vigilant for signs of danger. + +But Wazuh's might does not end there. It has been fully integrated with the famed Elastic Stack, a powerful search engine and tool for visualizing data. Through this integration, users may navigate through their security alerts with ease, as if wielding a crystal-clear map of their kingdom, revealing all the perils that threaten their borders. + +Wazuh brings robust security to all IT assets, combining the powers of Security Information and Event Management (SIEM) and Extended Detection and Response (XDR). It watches over the domain with unblinking eyes, scanning for threats and delivering swift responses to protect what is most valuable. The use cases of Wazuh are many and varied, all designed to safeguard your digital treasures and strengthen the walls of your cybersecurity posture. + +Use-cases: +- Configuration Assessment +- Malware Detection +- File Integrity Monitoring +- Threat Hunting +- Log Data Analysis +- Vulnerability Detection +- Incident Response +- Regulatory Compliance +- IT Hygiene +- Containers Security +- Posture Management +- Workload Protection + +## DevOps and DevSecOps Integration + + + +The integration should be as natural as the turning of the seasons, an organic and seamless process that unfolds with time. It is not a single task to be completed and forgotten, but a continuous journey, like the flowing of a river that ever shapes the land it touches. Though at times it may call for a shift in the very culture of the organization, such change is not forced, but arises naturally, like the slow awakening of spring after the long winter—an inevitable transformation in the pursuit of a more harmonious craft. + +And as in all great works of creation, what we forge must be shaped by the needs of our people and our lands. The processes we follow and the tools we wield must be chosen with wisdom, fitting the unique contours of our organization, much like a sword is balanced to the hand of the warrior who bears it. Only then can the integration thrive, as both DevOps and DevSecOps become not separate disciplines, but part of the same living tapestry, woven together in purpose and vision. diff --git a/ubuntu_on_fdd7_article/.DS_Store b/ubuntu_on_fdd7_article/.DS_Store deleted file mode 100644 index 9021dbf..0000000 Binary files a/ubuntu_on_fdd7_article/.DS_Store and /dev/null differ diff --git a/ubuntu_on_fdd7_article/pic/.DS_Store b/ubuntu_on_fdd7_article/pic/.DS_Store deleted file mode 100644 index 5008ddf..0000000 Binary files a/ubuntu_on_fdd7_article/pic/.DS_Store and /dev/null differ